web-dev-qa-db-ja.com

Javascript:forループを使用して配列を配列にプッシュします

これを説明してください。 forループを使用して配列の配列を作成しようとしています。それがうまくいかなかったとき、私はJavascriptが何をしているのかを理解するためにコードを単純化しようとしましたが、単純なコードも意味がありません。

function test(){
    var sub_array = [];
    var super_array =[];
    for (var i=1;i<=3;i++){
        sub_array.Push(i);
        super_array.Push(sub_array);
    }
    alert(super_array);
}

[1; 1,2; 1,2,3]。代わりに、[1,2,3; 1,2,3; 1,2,3]。 0〜2をループしてインデックスで割り当てると、同じ現象が発生します。

8

常に同じ配列への参照をスーパー配列にプッシュしています。

この問題を解決するには、 slice() を使用して、サブ配列をプッシュする前にクローンを作成します。

_function test() {
    var sub_array = [];
    var super_array = [];
    for (var i = 1; i <= 3; i++) {
        sub_array.Push(i);
        super_array.Push(sub_array.slice(0));
    }
    alert(super_array);
}
_

EDIT:Dan D.が以下で正しく指摘しているように、slice(0)この記事 (私は自分で測定しませんでした)によると、より高速です:

_for (var i = 1; i <= 3; i++) {
    sub_array.Push(i);
    super_array.Push(sub_array.concat());
}
_
16

「sub_array」をプッシュするときは、そのcopyをプッシュしていません。 「super_array」で同じ配列を3回取得します。 (参照を同じ配列に3回プッシュしていると言う必要があります。)

あなたはこれを行うことができます:

    // ...
    super_array.Push(sub_array.slice(0));

コピーを作成します。

6
Pointy

上手。配列、オブジェクト、関数などはjavascriptの参照である(Numbers(Int、Floatsなど)と文字列のみが「値で」渡される、つまり値がコピー/複製される)ことを理解する必要があります。 _var a=[];_があり、_var b=a_と言ってb.Push("bla")を追加し、aに警告すると、bに追加した場合でも、「bla」エントリが表示されます。言い換えると; aとbは、「左側の砂があなたのためです」と言っているお母さんからのフリッジのメモのようにjavascriptすることです。そして、あなたは知っています、冷蔵庫からの任意のサンドイッチだけでなく、左側のものを取ることです。彼女はまたあなたの家のドアに別のメモ(変数b)を書いていたかもしれません。もし彼女がサンドイッチをドアに貼り付けていたら..まあ、それは厄介でしょう。そしてJSはそれについて同じことを考えています:)

したがって、問題の解決策は休閑地です。

_function test(){
    var super_array =[];
    for (var i=1;i<=3;i++){
        var subarray=[];
        for (var u=1;u<=4-i;u++){
            sub_array.Push(u);
            super_array.Push(subarray);
        }
    }
    alert(super_array);
}
_

サブ配列を再定義することにより、新しい参照を作成します。そのため、変数b(家のドアの2番目の音符)が別のサンドイッチ(おそらくお父さんのサンドイッチ)の方向を指すようになります。

私はあなたがこれを理解するのを手伝うことができると思います。

2
japrescott

Forループの各反復で、同じ配列をsuper_arrayにプッシュしていることに注意してください。代わりに次を試してください:

function test(){
    var sub_array = [];
    var super_array =[];
    for (var i=1;i<=3;i++){
        sub_array = sub_array.slice(0,sub_array.length);
        sub_array.Push(i);
        super_array.Push(sub_array);
    }
    alert(super_array);
}
1

これは、super_arrayに追加するのと同じsub_arrayです。それで、なぜそれが違うのか。

新しい配列を作成してsuper_arrayにプッシュしているのではありません。

0

sub_arrayは、参照としてsuper_arrayに保存されます。つまり、sub_arrayを変更すると、super_array内に変更が反映されます。

0
James Wiseman