2016-06-16 16 views
1
var alph = ["a", "b", "c"]; 
var r = []; 

for(var i = 0; i < 5; i += 1) { 
    r.push(alph); 
} 

r[0].reverse(); 
console.log(r); 

/* Output 

[ [ 'c', 'b', 'a' ], 
    [ 'c', 'b', 'a' ], 
    [ 'c', 'b', 'a' ], 
    [ 'c', 'b', 'a' ], 
    [ 'c', 'b', 'a' ] ] 

*/ 

/* Expected output 

[ [ 'c', 'b', 'a' ], 
    [ 'a', 'b', 'c' ], 
    [ 'a', 'b', 'c' ], 
    [ 'a', 'b', 'c' ], 
    [ 'a', 'b', 'c' ] ] 

*/ 

配列内に配列があります。最初の配列を逆にする必要があります。私はr[0].reverse()がこれを行うと思ったが、代わりには逆すべての配列を逆転させた。配列の配列を逆にする配列内のすべての配列を逆にする

これはなぜ起こるのか誰かが説明できますか?

+0

効果がreverse' 'にローカライズされていません。あなたは 'r [0] [3] =" d "'を実行することができ、同様に "all arrays"を一度に変更します。それは実際には1つの配列です。 – 4castle

+0

オブジェクトはJSの参照型です。配列を複製する必要があります。 – Redu

答えて

7

配列の参照をプッシュしているため、配列の参照はすべて単一配列を参照しているため、配列を更新すると残りの部分が変更されます。代わりに、アレイのコピーをコピーするために元の配列のコピーをプッシュしてくださいArray#sliceメソッド。あなたは(それが値ではなく、参照渡しされています)r 5回に同じ配列をプッシュしている:あなたはpushrにするとき

var alph = ["a", "b", "c"]; 
 
var r = []; 
 

 
for (var i = 0; i < 5; i += 1) { 
 
    // push the exact copy of original array 
 
    r.push(alph.slice()); 
 
} 
 

 
r[0].reverse(); 
 
console.log(r);

4

新しい配列の配列を作成していません。したがって、r[0]上の操作は実際にはalphを更新しているため、他のすべての参照も更新されます。

0

実際に@Pranav C Balanのようなスライスメソッドを使用できますが、配列が多次元の場合は失敗します。機能を保護するには、Array.prototype.clone()のようなものが必要です。やってみましょう。

Array.prototype.clone = function(){ 
 
    return this.map(e => Array.isArray(e) ? e.clone() : e); 
 
}; 
 

 
var alph = [ 1, 2, 3, 4, [ 1, 2, [ 1, 2, 3 ], 4 ], 5 ], 
 
    cloned = [], 
 
    sliced = []; 
 
for(var i = 0; i < 5; i += 1) { 
 
    cloned.push(alph.clone()); 
 
    sliced.push(alph.slice()); 
 
} 
 

 
cloned[0][4][2].reverse(); // only the array at index pos 0,4,2 gets reversed 
 
sliced[0][4][2].reverse(); // all sub arrays at index 4,2 get reversed 
 
console.log(JSON.stringify(cloned)); 
 
console.log(JSON.stringify(sliced));

関連する問題