9

ループ内で長さが変化している配列を反復する信頼できる方法や標準的な方法があるかどうか、またその方法は何なのか疑問に思っています。これを行うたびに、これを行うために別の方法を選択することになるので、私は尋ねます。

for ( var i = 0; i < myarray.length; i++ ) {
  if (myarray[i] === 'something') {
    myarray.splice(i, 1);

    // *to avoid jumping over an element whose index was just shifted back to the current i
    i--;
  }
}

また

var i = 0;
while (myarray[i]) {
  if (myarray[i] === 'something') {
    myarray.splice(i, 1);
  } else {
    i++;
  }
}

これらは私がこれを行っていることに気付いた方法ですが、標準的なアプローチがあるかどうかに興味があります。

4

2 に答える 2

23

反対方向に反復する方が簡単だと思います:

for (var i=myarray.length; i--; ) {
   if (myarray[i] === 'something') myarray.splice(i, 1);
}

この方法では、削除時に増分を変更する必要はありません。

多くの開発者、特に JavaScript の前に C に似た言語を扱ったことのない開発者は、デクリメント演算子の微妙な部分を扱うのが難しいと感じています。私が書いたループは次のように書くこともできます

for (var i=myarray.length-1; i>=0; i--) {
于 2013-06-26T12:05:53.627 に答える
0

どのように選択しても、逆から始めてカウントダウンするのが最も簡単です。また、配列がスパースかどうか、およびスパースのままにしたい場合にも依存します。最も簡単なのは、再利用可能な関数と独自のライブラリを作成することです。あなたはこれを行うことができます。true に設定compressすると、配列は疎配列ではなく連続配列になります。この関数は、一致した値の出現をすべて削除し、削除された要素の配列を返します。

Javascript

function is(x, y) {
    if (x === y) {
        if (x === 0) {
            return 1 / x === 1 / y;
        }

        return true;
    }

    var x1 = x,
        y1 = y;

    return x !== x1 && y !== y1;
}

function removeMatching(array, value /*, compress (default = false)*/ ) {
    var removed = [],
        compress = arguments[2],
        index,
        temp,
        length;

    if (typeof compress !== "boolean") {
        compress = false;
    }

    if (compress) {
        temp = [];
        length = array.length;
        index = 0;
        while (index < length) {
            if (array.hasOwnProperty(index)) {
                temp.push(array[index]);
            }

            index += 1;
        }
    } else {
        temp = array;
    }

    index = 0;
    length = temp.length;
    while (index < length) {
        if (temp.hasOwnProperty(index) && is(temp[index], value)) {
            if (compress) {
                removed.push(temp.splice(index, 1)[0]);
            } else {
                removed.push(temp[index]);
                delete temp[index];
            }
        }

        index += 1;
    }

    if (compress) {
        array.length = 0;
        index = 0;
        length = temp.length;
        while (index < length) {
            if (temp.hasOwnProperty(index)) {
                array.push(temp[index]);
            }

            index += 1;
        }
    }

    return removed;
}

var test = [];

test[1] = 1;
test[50] = 2;
test[100] = NaN;
test[101] = NaN;
test[102] = NaN;
test[200] = null;
test[300] = undefined;
test[400] = Infinity;
test[450] = NaN;
test[500] = -Infinity;
test[1000] = 3;

console.log(test);
console.log(removeMatching(test, NaN));
console.log(test);
console.log(removeMatching(test, Infinity, true));
console.log(test);

出力

[1: 1, 50: 2, 100: NaN, 101: NaN, 102: NaN, 200: null, 300: undefined, 400: Infinity, 450: NaN, 500: -Infinity, 1000: 3]
[NaN, NaN, NaN, NaN]
[1: 1, 50: 2, 200: null, 300: undefined, 400: Infinity, 500: -Infinity, 1000: 3]
[Infinity]
[1, 2, null, undefined, -Infinity, 3] 

jsfiddleについて

于 2013-06-26T13:01:49.517 に答える