多维数组索引不工作的js

时间:2016-11-12 20:16:36

标签: javascript arrays multidimensional-array indexof

我正在尝试在二维数组中找到一个数字的索引,但是控制台发出了

未捕获的TypeError:block [((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);
                }
            }

        }

    }
}

2 个答案:

答案 0 :(得分:0)

您有分配给数组的混合数据类型。当用户输入非数字值时,您确实将嵌套数组分配给其中一个元素,但在用户输入有效数字时则不是这样。

根据我的想法(Sudoko游戏?),这可能是有意的:数字是网格中的已知值,嵌套数组表示在该特定单元格中仍然可能的值列表。

但是在代码的第二部分中,您应该检查两种情况中的哪一种,因为如果您正在查看的值确实是一个数组,您只想删除数组元素。您可以使用Array.isArray()进行此测试。

脚本的第二部分还有一些其他问题:

  • 表达式block[a][b]与您填充该数组的方式不一致:它应该block[a*10+b]保持一致。
  • b中的.indexOf(b)错误:您不是在寻找该值,而是block[a*10+b]
  • 即使splice()返回indexOf,也会始终执行-1。这会导致不希望的效果,因为如果splice()的第一个参数为负,则索引实际上是从数组的末尾开始计算的,并且仍然会从数组中删除一个元素。这不应该发生:如果splice结果是非负的,您应该只执行indexOf

下面我已经提出了一个工作版本,但是为了避免几乎无休止的提示,我提供了一个文本片段,您可以一次输入完整的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,并且每个“行”只存储9个值时,总会有一个索引保持不变。

答案 1 :(得分:0)

我没有看过你的第二个for循环,但你可以尝试在我提供的代码片段中应用类似的逻辑。问题是您需要在外部for循环内创建一个临时数组,其值超过a(但不在内部,嵌套for循环中,而不是b的值)。在for的{​​{1}}循环内,您需要b进入该临时数组(我称之为push)。然后,在temp b循环之外,但在for的下一次迭代之前,将该临时数组a推送到temp数组。这样,您将生成一个2D数组。

&#13;
&#13;
block
&#13;
&#13;
&#13;