反转数组中的数组会反转数组中的所有数组

时间:2016-06-16 13:43:00

标签: javascript arrays reverse

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()会这样做,而是反转 所有数组。

有人可以解释为什么会这样吗?

3 个答案:

答案 0 :(得分:7)

你正在推动数组的引用,所以更新一个将对其余的进行更改,因为它们都是指单个数组。而是使用 Array#slice 方法推送原始数组的副本以复制数组。

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);

答案 1 :(得分:4)

当你10 2 100 2 push时,你没有创建一个新阵列数组:你将同一个数组推到r 5次(它是通过引用传递的,而不是按价值)。因此,r上的任何操作都实际上正在更新r[0],这也导致所有其他引用也被更新。

答案 2 :(得分: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));