我面对一些我不理解的数组。实际上,我创建了一个我用空子数组填充的数组来获得2D矩阵。 但是当我操纵数组时,它的行为并不像我预期的那样。
var arr = new Array(5);
arr.fill([]);
arr[2].push("third rank item");
console.log(arr);
//[ [ 'third rank item' ],
// [ 'third rank item' ],
// [ 'third rank item' ],
// [ 'third rank item' ],
// [ 'third rank item' ] ]
欢迎这件事的每一个亮点
答案 0 :(得分:7)
这与数组(以及通常的对象)是引用而不是值是一样的老问题。
具体来说,当您执行arr.fill([])
时,您将获取一个空的数组并使用它来填充父数组。
就像说:
var arr = new Array(5);
arr[0] = arr[1] = arr[2] = arr[3] = arr[4] = [];
它们都引用相同的数组!所以当你继续修改其中一个时,看起来它们都被修改了(但实际上它仍然是相同的)
不幸的是,没有简单的方法为每个人分配一个空数组。你可以这样做:
Array.apply(null, Array(5)).map(function() {return [];});
基本上,创建一个长度为5的(初始化的)空数组,并将每个(空)值映射到新的[]
。
Array.from
代替Array.apply(null, Array(5)).map
,如下所示:
Array.from( new Array(5), function() { return []; } );
答案 1 :(得分:2)
Array.prototype.fill的ECMA doc的第11行显然给出了神秘的原因。
重复,而k <最终
设Pk为ToString(k)。
设setStatus(O,Pk,value,true)。
ReturnIfAbrupt(setStatus)。
将k增加1。
这里“价值”只是收到的参考。他们将它设置为直接排列的属性。这意味着所有填充的数组只是对单个数组对象的引用。
答案 2 :(得分:1)
正如您可以注意到使用array.fill,您将使用对同一数组的引用来填充数组,
如果要将每个数组索引实例化为空数组,则正常的while循环将执行:
var arr = [];
var n = 5
while(n--)
arr[n] = []
arr[2].push("third rank item");
console.log(arr);
&#13;
选项2:
如果你有lodash包可用,你也可以使用_.map,因为这是专门设计来循环一个稀疏数组(原生地图将跳过非初始值)
var arr =_.map(new Array(5), (x => []))
arr[2].push("third rank item");
console.log(arr)
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>
&#13;
答案 3 :(得分:1)
它发生了引用的原因。数组是一种对象,当你用[] or new Array()
只填充运行数组填充你的数组时,对象就会对它们的引用起作用,并在所有索引中放入相同的数组,这就是为什么当你更新子数组时更新。
解决方案:
let arr = new Array(5).fill(0).map(ele => ele = []);
arr[2].push("something");
OR
let arr = Array.of([], [], [], []);
arr[2].push("something");
结果:正如预期的那样,只更新了arr
的2个索引。
答案 4 :(得分:0)
你可以试试这个,
var arr = new Array(5);
var i = 0;
while (i < arr.length)
arr.fill([], i++);
arr[2].push("third rank item");
console.log(arr);
&#13;
答案 5 :(得分:0)
试试这个,这是一行中的快速解决方案。
var arr = new Array(5);
arr = Array.from(arr, x => []);
arr[2].push("third rank item");
console.log(arr);
答案 6 :(得分:0)
对于ES6,我建议使用此方法来创建2个或多维数组:
// create an M x N dimension grid and fill it with 0's
const myArray = [...Array(M)].map(r => [...Array(N)].map(r => 0));