多维数组indexOf不起作用js
multidimensional array indexOf not working js
我试图在二维数组中查找数字的索引,但控制台给出了
未捕获类型错误:块[((a * 10) + c)].indexOf 不是函数
我觉得跟数组元素的访问方式有关系,但是好像找不到问题
这是代码。
var block = [];
var temp;
var del;
for(var a = 0;a < 9;a++){
for(var b = 0;b < 9;b++){
temp = parseInt(prompt("enter element number " + b + " of row number " + a));
console.log(temp);
if(temp>0){
block[a*10+b] = temp;
}else{
block[a*10+b] = [1,2,3,4,5,6,7,8,9];
}
// console.log(block[a*10+b]);
}
}
for(var a = 0;a < 9;a++){
for(var b = 0;b < 9;b++){
if(typeof(block[a][b]) == "number"){
for(var c = 0;c < 9;c++){
if(c != b){
del = block[a*10+c].indexOf(b);
block[a*10+c].splice(del,1);
}
}
}
}
}
您将混合数据类型分配给了 块 数组。当用户输入一个非数字值时,您确实将嵌套数组分配给 block 元素之一,但当用户输入有效数字时并非如此。
从我认为您正在做的事情(数独游戏?)来看,这可能是有意的:数字是网格中的已知值,嵌套数组表示在该特定单元格中仍然可能的值列表。
但是在代码的第二部分,您应该检查您属于这两种情况中的哪一种,因为如果您正在查看的值确实是一个数组,您只想删除数组元素。您可以使用 Array.isArray()
进行此测试。
您脚本的第二部分还有一些其他问题:
- 表达式
block[a][b]
与您填充该数组的方式不一致:它应该是 block[a*10+b]
才能保持一致。
.indexOf(b)
中的 b
是错误的:您不是在寻找那个值,而是在寻找 block[a*10+b]
.
- 总是执行
splice()
,即使 indexOf
返回 -1
。这会导致不良影响,因为如果 splice()
的第一个参数为负数,索引实际上是从数组末尾开始计算的,并且仍然从数组中删除了一个元素。这不应该发生:如果 indexOf
结果是非负的,你应该只执行 splice
。
下面我放了一个工作版本,但是为了避免几乎没完没了的提示,我为这段代码提供了一个文本区域,您可以在其中一次性输入完整的 9x9 网格,然后按一个按钮开始代码的执行:
document.querySelector('button').onclick = function () {
var block = [];
var temp;
var del;
var text = document.querySelector('textarea').value.replace(/\s+/g, '');
for(var a = 0;a < 9;a++){
for(var b = 0;b < 9;b++){
temp = parseInt(text[a*9+b]); // <-- get char from text area
if(temp>0){
block[a*10+b] = temp;
}else{
block[a*10+b] = [1,2,3,4,5,6,7,8,9];
}
}
}
for(var a = 0;a < 9;a++){
for(var b = 0;b < 9;b++){
var num = block[a*10+b]; // <-- get content, fix the index issue
if(typeof num == "number"){
for(var c = 0;c < 9;c++){
if(c != b && Array.isArray(block[a*10+c])){ //<-- add array-test
del = block[a*10+c].indexOf(num); // <-- not b, but num
if (del > -1) // <-- only splice when found
block[a*10+c].splice(del,1);
}
}
}
}
}
document.querySelector('pre').textContent = 'block='+ JSON.stringify(block);
};
<textarea rows=9>
53..7....
6..195...
.98....6.
8...6...3
4..8.3..1
7...2...6
.6....28.
...419..5
....8..79
</textarea>
<button>Process</button>
<pre></pre>
请注意,block
中的元素仍为 null
。我想你是故意的:当你将 a
乘以 10,并且每个 "row" 只存储 9 个值时,总是有一个索引保持不变。
我没有查看您的第二个 for
循环,但您可以尝试在此处应用与我提供的代码片段中类似的逻辑。问题是您需要在外部 for
循环内创建一个临时数组 a
的值(但不是在内部嵌套 for
循环内 b
的值).在 for
循环中获取 b
的值,然后,您需要将某些内容 push
放入该临时数组(我称之为 temp
)。然后,在 b
for
循环之外,但在 a
的下一次迭代之前,将临时数组 temp
推送到 block
数组。这样,你将生成一个二维数组。
var block = [];
var del;
for(var a = 0; a < 9; a++) {
let temp = [];
for(var b = 0; b < 9; b++) {
let num = parseInt(prompt(`Enter element ${b} of row ${a}:`));
if (num > 0) {
temp.push(num);
} else {
// block[a*10+b] = [1,2,3,4,5,6,7,8,9];
temp.push(b);
}
}
block.push(temp);
}
我试图在二维数组中查找数字的索引,但控制台给出了
未捕获类型错误:块[((a * 10) + c)].indexOf 不是函数
我觉得跟数组元素的访问方式有关系,但是好像找不到问题
这是代码。
var block = [];
var temp;
var del;
for(var a = 0;a < 9;a++){
for(var b = 0;b < 9;b++){
temp = parseInt(prompt("enter element number " + b + " of row number " + a));
console.log(temp);
if(temp>0){
block[a*10+b] = temp;
}else{
block[a*10+b] = [1,2,3,4,5,6,7,8,9];
}
// console.log(block[a*10+b]);
}
}
for(var a = 0;a < 9;a++){
for(var b = 0;b < 9;b++){
if(typeof(block[a][b]) == "number"){
for(var c = 0;c < 9;c++){
if(c != b){
del = block[a*10+c].indexOf(b);
block[a*10+c].splice(del,1);
}
}
}
}
}
您将混合数据类型分配给了 块 数组。当用户输入一个非数字值时,您确实将嵌套数组分配给 block 元素之一,但当用户输入有效数字时并非如此。
从我认为您正在做的事情(数独游戏?)来看,这可能是有意的:数字是网格中的已知值,嵌套数组表示在该特定单元格中仍然可能的值列表。
但是在代码的第二部分,您应该检查您属于这两种情况中的哪一种,因为如果您正在查看的值确实是一个数组,您只想删除数组元素。您可以使用 Array.isArray()
进行此测试。
您脚本的第二部分还有一些其他问题:
- 表达式
block[a][b]
与您填充该数组的方式不一致:它应该是block[a*10+b]
才能保持一致。 .indexOf(b)
中的b
是错误的:您不是在寻找那个值,而是在寻找block[a*10+b]
.- 总是执行
splice()
,即使indexOf
返回-1
。这会导致不良影响,因为如果splice()
的第一个参数为负数,索引实际上是从数组末尾开始计算的,并且仍然从数组中删除了一个元素。这不应该发生:如果indexOf
结果是非负的,你应该只执行splice
。
下面我放了一个工作版本,但是为了避免几乎没完没了的提示,我为这段代码提供了一个文本区域,您可以在其中一次性输入完整的 9x9 网格,然后按一个按钮开始代码的执行:
document.querySelector('button').onclick = function () {
var block = [];
var temp;
var del;
var text = document.querySelector('textarea').value.replace(/\s+/g, '');
for(var a = 0;a < 9;a++){
for(var b = 0;b < 9;b++){
temp = parseInt(text[a*9+b]); // <-- get char from text area
if(temp>0){
block[a*10+b] = temp;
}else{
block[a*10+b] = [1,2,3,4,5,6,7,8,9];
}
}
}
for(var a = 0;a < 9;a++){
for(var b = 0;b < 9;b++){
var num = block[a*10+b]; // <-- get content, fix the index issue
if(typeof num == "number"){
for(var c = 0;c < 9;c++){
if(c != b && Array.isArray(block[a*10+c])){ //<-- add array-test
del = block[a*10+c].indexOf(num); // <-- not b, but num
if (del > -1) // <-- only splice when found
block[a*10+c].splice(del,1);
}
}
}
}
}
document.querySelector('pre').textContent = 'block='+ JSON.stringify(block);
};
<textarea rows=9>
53..7....
6..195...
.98....6.
8...6...3
4..8.3..1
7...2...6
.6....28.
...419..5
....8..79
</textarea>
<button>Process</button>
<pre></pre>
请注意,block
中的元素仍为 null
。我想你是故意的:当你将 a
乘以 10,并且每个 "row" 只存储 9 个值时,总是有一个索引保持不变。
我没有查看您的第二个 for
循环,但您可以尝试在此处应用与我提供的代码片段中类似的逻辑。问题是您需要在外部 for
循环内创建一个临时数组 a
的值(但不是在内部嵌套 for
循环内 b
的值).在 for
循环中获取 b
的值,然后,您需要将某些内容 push
放入该临时数组(我称之为 temp
)。然后,在 b
for
循环之外,但在 a
的下一次迭代之前,将临时数组 temp
推送到 block
数组。这样,你将生成一个二维数组。
var block = [];
var del;
for(var a = 0; a < 9; a++) {
let temp = [];
for(var b = 0; b < 9; b++) {
let num = parseInt(prompt(`Enter element ${b} of row ${a}:`));
if (num > 0) {
temp.push(num);
} else {
// block[a*10+b] = [1,2,3,4,5,6,7,8,9];
temp.push(b);
}
}
block.push(temp);
}