4

私は現在、このように反復する配列データ構造を持っており、foo要素の一意の各ペアを呼び出しています。

for(var i = 0; i < arr.length; i++) {
    for(var j = i + 1; j < arr.length; j++) {
        foo(arr[i], arr[j]);
    }
}

ただし、名前で要素を簡単に追加および削除できるため、配列ではなくオブジェクトを使用したいことに気付きました。

ただし、そのようなオブジェクトを反復処理する明確な方法はわかりません。私が得ることができる最も近いものは次のとおりです。

for(i in obj) {
    for(j in obj) {
        foo(obj[i], obj[j]);
    }
}

明らかに、これは各ペアを2回実行し、同じ要素のペアを生成します。最初のコードサンプルの配列で行うのと同じ方法で、オブジェクトを反復処理する簡単な方法はありますか?

アップデート:

jsperfでのソリューションのパフォーマンステスト。

4

5 に答える 5

5

最初はコメントとして書かれた私の解決策:

if (i < j)内側のループに条件を追加します。foo(2, 10)これは最善の解決策ではないかもしれませんが、foo関数がとに対して同じことを行う限り機能しますfoo(10, 2)

for(i in obj) {
    for(j in obj) {
        if (i < j) {
            foo(obj[i], obj[j]);
        }
    }
}
于 2012-05-08T20:29:07.930 に答える
2

たぶん、未設定の使用済みオブジェクトを試すことができます:

for(i in obj) {
    var a = obj[i];
    delete obj[i];
    for(j in obj) {
        foo(a, obj[j]);
    }
}

http://jsfiddle.net/bXcvb/

オリジナルの obj が必要な場合は、JavaScript オブジェクトを正しく複製するにはどうすればよいですか? を参照してください。

于 2012-05-08T19:55:20.473 に答える
2

私があなたの質問を理解していると仮定すると...値が外側のループによってすでにアクセスされているかどうかを確認してください。

var visited = {}
for(i in obj) {
    visited[i] = true;
    for(j in obj) {
        if(j in visited){ continue; }
        foo(obj[i], obj[j]);
    }
}
于 2012-05-08T19:44:27.290 に答える
2

Object.keys() を使用して、キーのリストを配列として取得します。

keys = Object.keys();
for(i=0;i<keys.length;i++) {
    for(j=i+1;j<keys.length;j++) {
        foo(obj[keys[i]], obj[keys[j]]);
    }
}
于 2012-05-08T19:50:21.550 に答える
1

オブジェクト キーを配列にプッシュできます。

var obj_keys = [];
for (i in obj) {
  obj_keys.push(i);
}

for(i = 0; i < obj_keys.length; ++i) {
    for(j = i + 1; j < obj_keys.length; ++j) {
        foo(obj[obj_keys[i]], obj[obj_keys[j]]);
    }
}
于 2012-05-08T19:47:19.893 に答える