我正在尝试测试数组是否有数字 1 到 9。我有 9 个不同的数组要测试,所以我正在尝试逐个循环数组集并将其转换为字符串并测试该数组是否有数字 1 到 9。当我输出我的代码时,它显示为
[true, true, true, true, true, true, true, true, false]
最后一个应该为假,因为数组[8]不包含从1到9的所有数字。我不确定我的正则表达式编码是否错误,但对于应该为假的数组,测试打印出 true。
function doneOrNot(board){
var numberTest = /[1-9]/g;
var boardStr = "";
var boardTest;
var testResult = [];
for(var i = 0; i < board.length; i++) {
boardStr = board[i].toString();
boardTest = numberTest.test(boardStr);
testResult.push(boardTest);
console.log(boardStr);
}
console.log(testResult);
}
doneOrNot([[5, 3, 4, 6, 7, 8, 9, 1, 2],
[6, 7, 2, 1, 9, 0, 3, 4, 9],
[1, 0, 0, 3, 4, 2, 5, 6, 0],
[8, 5, 9, 7, 6, 1, 0, 2, 0],
[4, 2, 6, 8, 5, 3, 7, 9, 1],
[7, 1, 3, 9, 2, 4, 8, 5, 6],
[9, 0, 1, 5, 3, 7, 2, 1, 4],
[2, 8, 7, 4, 1, 9, 6, 3, 5],
[3, 0, 0, 4, 8, 1, 1, 7, 9]]);
则表达式根本不是合适的工具。 它不会告诉您每个数字是否存在。 它告诉您是否存在任何数字,或者不同形式的正则表达式可以告诉您是否只有数字存在,但它不会告诉您每个数字是否存在(以任何顺序)。
下面是一种概念上简单的方法,用于测试任何给定数组以查看是否所有数字 1-9 都存在:
function test(arr) {
for (var i = 1; i <= 9; i++) {
if (arr.indexOf(i) === -1) {
return false;
}
}
return true;
}
而且,您可以将其与测试数据相结合:
function doneOrNot(list) {
return list.map(function(arr) {
return test(arr);
});
}
doneOrNot([[5, 3, 4, 6, 7, 8, 9, 1, 2],
[6, 7, 2, 1, 9, 0, 3, 4, 9],
[1, 0, 0, 3, 4, 2, 5, 6, 0],
[8, 5, 9, 7, 6, 1, 0, 2, 0],
[4, 2, 6, 8, 5, 3, 7, 9, 1],
[7, 1, 3, 9, 2, 4, 8, 5, 6],
[9, 0, 1, 5, 3, 7, 2, 1, 4],
[2, 8, 7, 4, 1, 9, 6, 3, 5],
[3, 0, 0, 4, 8, 1, 1, 7, 9]]);
工作演示:http://jsfiddle.net/jfriend00/w04b6frv/
仅供参考,可能有更花哨的计划可能会表现得更好。 上面的要点是找到概念上最简单的机制,只要数组包含 9 位数字中的每一个,它就可以工作并容忍任何输入。
我不了解您的测试数组的所有约束,但是如果您真的想看看数组中是否恰好有 9 个元素,其中包括从 1 到 9 的所有数字,并且可以按任何顺序排列,那么您可以这样做:
function test(arr) {
var s = arr.slice(0).sort().toString();
return s === "1,2,3,4,5,6,7,8,9";
}
工作演示:http://jsfiddle.net/jfriend00/6cdg5b3g/
而且,这是一种不同的方法,从 9 位位掩码
开始,然后在每次找到 1-9 位数字之一时清除一点,然后它只能查看最后是否清除了整个位掩码。 此版本允许 1-9 范围之外的值(以及长度超过 9 的数组),但只需检查开头是否9
长度即可轻松更改。
function test(arr) {
// initalize bits to 111111111 in binary
// one bit for each value 1-9
var bits = 511;
arr.forEach(function(item) {
// if the number is in range, then clear the appropriate bit
if (item >= 1 && item <= 9) {
bits &= ~(1 << (item - 1));
}
});
// return if all bits have been cleared
return bits === 0;
}
工作演示:http://jsfiddle.net/jfriend00/nt1mya4d/
我建议
var testResult = board.map(function(arr) {
arr = arr.slice().sort(); // Copy and sort
for(var j=0; j<9; ++j) // Iterate numbers
if(arr[j] !== j+1) return false;
return true;
});
function doneOrNot(board){
var testResult = board.map(function(arr) {
arr = arr.slice().sort(); // Copy and sort
for(var j=0; j<9; ++j) // Iterate numbers
if(arr[j] !== j+1) return false;
return true;
});
console.log(testResult);
}
doneOrNot([[5, 3, 4, 6, 7, 8, 9, 1, 2],
[6, 7, 2, 1, 9, 0, 3, 4, 9],
[1, 0, 0, 3, 4, 2, 5, 6, 0],
[8, 5, 9, 7, 6, 1, 0, 2, 0],
[4, 2, 6, 8, 5, 3, 7, 9, 1],
[7, 1, 3, 9, 2, 4, 8, 5, 6],
[9, 0, 1, 5, 3, 7, 2, 1, 4],
[2, 8, 7, 4, 1, 9, 6, 3, 5],
[3, 0, 0, 4, 8, 1, 1, 7, 9]]);
您的错误是将整行转换为字符串并针对正则表达式测试整行。所以对于这一行:
[9, 0, 1, 5, 3, 7, 2, 1, 4]
但是,我们期望false
:
(/[1-9]/g).test([9, 0, 1, 5, 3, 7, 2, 1, 4].toString())
返回true
,因为字符串确实包含至少一个预期的数字。
您可以通过使用 match
而不是 test
来修复您的问题。 match
将返回字符串中的匹配项数,因此在这种情况下:
[9, 0, 1, 5, 3, 7, 2, 1, 4].toString().match(/[1-9]/g)
返回["9", "1", "5", "3", "7", "2", "1", "4"]
然后你可以计算比赛结果的长度,但是如果字符串包含两个"9"怎么办?你也需要让它独一无二。我建议将doneOrNot
功能简化为:
var done = '123456789';
function doneOrNot(board) {
var results = [];
for(var i = 0; i < board.length; i++) {
var boardStr = board[i].sort().join('');
results.push(boardStr === done);
}
console.log(results);
}
JSFiddle: http://jsfiddle.net/99bxLt3s/
更好的解决方案是使用另一个为您提供数组相等性检查的库。然后你可以像这样编写代码:
var done = [1, 2, 3, 4, 5, 6, 7, 8, 9];
function doneOrNot(board) {
var results = [];
for(var i = 0; i < board.length; i++) {
results.push(ArrayEquals(board[i], done));
}
console.log(results);
}
其中ArrayEquals
是比较外部库中两个数组相等的函数。