0

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

0

2 Answers 2

2

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" />

Sign up to request clarification or add additional context in comments.

1 Comment

Great, I tried to put the map also without the zeros fill, but Array() messed up with me. Thanks a lot ;)
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.