2012-01-25 11 views
6

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

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をループしてインデックスで割り当てると同じ現象が発生します。

答えて

6

「sub_array」を押すと、コピーがプッシュされていません。あなたは "super_array"で同じ配列を3回終了します。 (私はあなたが同じ配列へ参照を3回押していると言う必要があります。)

あなたがこれを行うことができます:コピーを作成するために

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

を。

0

スーパーアレイに追加するサブアレイと同じです。それでなぜ違うのですか?

あなたは新しい配列を作成せずに、スーパー配列にプッシュしていません。

13

あなたは常にスーパーアレイに同じアレイへの参照をプッシュしています。その問題を解決するために

、あなたはそれをプッシュする前に、サブ配列のクローンを作成するために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:ダンD.は当然以下の指摘するように、あなたはまた、引数なしconcat()を呼び出すことができますslice(0)の代わりに。それは高速ですthis articleに応じて(私はそれを自分自身を測定していない):

for (var i = 1; i <= 3; i++) { 
    sub_array.push(i); 
    super_array.push(sub_array.concat()); 
} 
+2

なぜ '.slice(0)'を使って '.concat()'ではなくArrayをコピーしたのですか?それは速いかもしれませんが、プロファイリングは私には分かりませんでした。 –

+0

興味深いことに、[このブログ](http://swingpants.com/2009/03/12/fastest-way-to-copy-an-array-concat-or-slice0/) 'concat()'は高速です。私は私の答えでそれを言及します。あなたのコメントをありがとう:) –

0

sub_arraysuper_arrayで参照として保存され、これはあなたがsub_arrayを変更すると変更はあなたがsuper_array

1

注内部で反射されることを意味しfor-loop内の各繰り返しに対して同じ配列を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); 
} 
+0

+1スライスを使用して、配列全体を複製するためにそれを使用しているときに任意のパラメータを渡す必要はありませんが、arr.slice()=== arr.slice(0、 arr.length) – wheresrhys

2

あなたは、その配列、オブジェクト、関数などがJavaScript(唯一の数値(Int、浮動小数点数など)と文字列が値によってコピー/複製されたことを意味する)で参照されていることを理解する必要があります! 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番目の音符)が別のサンドイッチの方向を指しているように - 多分パパのサンドイッチ。

私はあなたの理解を助けることができれば幸いです。

関連する問題