多维数组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);
}