荒谬的javascript错误:必须多次调用函数才能正常运行

时间:2010-11-21 18:01:39

标签: javascript loops

我毫不怀疑我自己的愚蠢对此负有责任。我不是一个程序员,而是一个科学家,而且我只是一直在捣乱,直到它起作用,这就是我最终得到如此奇怪的错误。基本上,任何帮助都会非常感激。

好的,我的功能是这样的:

function discardDuplicates(threshold) {
    for (var m = 0; m < xCo2.length; m++){
        var testX = xCo2[m];
        var testY = yCo2[m];
        for (var n = 0; n < xCo2.length; n++){
            if (m != n) {
                if ((Math.abs(xCo2[n] - testX) < threshold)
                    && (Math.abs(yCo2[n] - testY) < threshold)
                    && deltas[m] > deltas[n]){

                    xCo2.splice(n,1);
                    yCo2.splice(n,1);
                    deltas.splice(n,1);
                }
            }
        }
    }
}

我正在检测具有存储在xCo2和yCo2阵列中的坐标(x,y)的特征,每个坐标也具有称为“delta”的属性。我想检查一下我是否在基本相同的位置识别了几个功能 - 如果我有,它们可能是重复的,所以除了列表中具有最高增量的那个之外的所有功能。

对,基本上,这不起作用!

目前我必须这样做:

//ugly hack 
var oldLength = 0;
var newLength = 1;
while (oldLength != newLength) {
    oldLength = xCo2.length;
    discardDuplicates(10);
    newLength = xCo2.length;
}

因为第一次调用它的函数不会删除任何重复项。第二次它删除了大部分。第三次它通常都拥有它们......所以我只是继续调用它直到它停止删除重复项。该功能绝对有效;它正在消除正确的观点。

我问这个问题的原因是现在第二次发生了同样的错误,第二次使用了第二个函数,这次尝试删除delta值太低的任何坐标。

启蒙将被感激地接受!

1 个答案:

答案 0 :(得分:10)

在数组上调用splice将删除一个条目并将下一个条目移动到此位置,这是非常常见的错误。

我们来看看:

xCo2 = [1, 2, 3, 4, 5];
n = 0;

xCo2.splice(n, 1); // n = 0, removed 1
>> [2, 3, 4, 5];
n ++;

xCo2.splice(n, 1); // n = 1, removed 3
>> [2, 4, 5];
n++;

看到问题?您正在跳过条目,您需要做的是每次从数组中删除条目时减少n。由于您总是删除1个条目,因此在拼接阵列后需要将n减少一次。

if ((Math.abs(xCo2[n] - testX) < threshold)
     && (Math.abs(yCo2[n] - testY) < threshold) && deltas[m] > deltas[n] ){

    xCo2.splice(n,1);
    yCo2.splice(n,1);
    deltas.splice(n,1);
    n--;
}

PS:一些空格大大增加了代码的可读性。