Reputation: 2037
I'm trying to "paint" some grid with a rectangle area. But when I try to modify just one row the array modifies all of them. I tried to initialize the array in several ways, but the problem seems to be when I try to modify it, not the Array object.
var multiArray = Array(8).fill(Array(8).fill(false));
// Fill square 3x1 at (2, 4)
for (var i = 0; i < 3; i++) {
for (var j = 0; j < 1; j++) {
multiArray[2 + i][4 + j] = true;
}
}
document.getElementById("content").innerHTML =
multiArray.map(a => a.map(e => e ? 'X' : '0').join(''))
.join('<br />');
<div id="content" />
At this point instead of providing a solution for this case I only want to understand why is that happening. What's the problem with [][]
expression.
I'm trying this in Chrome version 51.0
Upvotes: 0
Views: 65
Reputation: 26161
Creating an N dimension array is a little tricky since arrays are of reference types. I had done something as follows previously. The arrayND
function takes sizes of each dimension as arguments and the last argument is the initializing value. I hope it helps.
Array.prototype.clone = function(){
return this.map(e => Array.isArray(e) ? e.clone() : e);
};
function arrayND(...n){
return n.reduceRight((p,c) => c = (new Array(c)).fill().map(e => Array.isArray(p) ? p.clone() : p ));
}
var arrND = arrayND(8,8,false);
console.log(arrND);
Upvotes: 0
Reputation: 150030
Array(8).fill(Array(8).fill(false))
only creates two arrays, one of which contains eight references to the other. This is more obvious if you break it into two lines - the following is equivalent:
var tempArray = Array(8).fill(false);
var multiArray = Array(8).fill(tempArray);
So that's not what you want. Try something like this instead:
var multiArray = Array(8).fill(0).map(_=>Array(8).fill(false));
I've filled the first array with zeros just as placeholders so that .map()
will visit all of those elements, then for each element my little map callback returns a new array filled with false
.
In context:
var multiArray = Array(8).fill(0).map(_=>Array(8).fill(false));
// fill square 3x1 at (2, 4)
for (var i = 0; i < 3; i++) {
for (var j = 0; j < 1; j++) {
multiArray[2 + i][4 + j] = true;
}
}
document.getElementById("content").innerHTML =
multiArray.map(a => a.map(e => e ? 'X' : '0').join(''))
.join('<br />');
<div id="content" />
Upvotes: 2