我试图测试数组是否有数字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]]);
答案 0 :(得分:7)
正则表达式根本不是正确的工具。它不会告诉您每个数字是否存在。它会告诉您是否存在任何数字,或者正则表达式的其他形式是否可以告诉您是否存在数字,但它并不会告诉您每个数字是否存在(按任何顺序)。
这是一个概念上简单的方法,用于测试任何给定的数组以查看是否存在所有数字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;
}
答案 1 :(得分:2)
我建议
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]]);
答案 2 :(得分:1)
您的错误是您将整行转换为字符串并针对正则表达式测试整行。所以对于这一行:
[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"]
然后你可以计算匹配结果长度但是如果字符串包含两个&#34; 9&#34 ;?你也需要让它独一无二。我建议将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
是将两个数组从外部库中进行相等性比较的函数。