10

I would like to create a two-dimensional array that gets initialized with booleans which are set to false. Currently I'm using this method of array creation:

const rows = 3
const cols = 5

const nestedArray = new Array(rows).fill(
    new Array(cols).fill(false)
)

The nestedArray looks fine, but as soon as I change the value of nestedArray[0][2], the values of nestedArray[1][2] and nestedArray[2][2] also get changed.

I guess this is because the sub-arrays are identical, probably because they get filled into the parent array by reference and not by value.

What would be an elegant and efficient way of creating an array of non-identical sub-arrays instead?

lsgng
  • 465
  • 8
  • 22

6 Answers6

10

You can use nested Array.from() calls:

const rows = 3
const cols = 5

const nestedArray = Array.from({ length: rows }, () => 
  Array.from({ length: cols }, () => false)
);
  
nestedArray[0][1] = 'value'; // example of changing a single cell
  
console.log(nestedArray);
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
5

You could use Array.from method to create rows where second parameter is map method, and Array.fill for columns.

const rows = 3
const cols = 5

const nestedArray = Array.from(Array(rows), _ => Array(cols).fill(false));
nestedArray[0][1] = true;
console.log(nestedArray)

Another approach would be to use spread syntax ... on rows array so you can then use map method on that array.

const rows = 3
const cols = 5

const nestedArray = [...Array(rows)].map(_ => Array(cols).fill(false))
nestedArray[0][1] = true;
console.log(nestedArray)
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
1

There are already a lot of answers but maybe someone find this one more readable:

let rows = 3;
let columns = 5;
let rowTemplate = Array(columns).fill(false);
let matrix = Array.from(Array(rows), () => [...rowTemplate]);

matrix[1][3] = true;
/*
[
  [ false, false, false, false, false ],
  [ false, false, false, true, false ],
  [ false, false, false, false, false ]
]
*/
zajer
  • 649
  • 6
  • 17
0
const nestedArray = Array(rows).fill(false).map(x => Array(cols).fill(false))

try this one

Dheeraj Kumar
  • 119
  • 2
  • 12
  • 1
    While this answer is probably correct and useful, it is preferred if you include some explanation along with it to explain how it helps to solve the problem. This becomes especially useful in the future, if there is a change (possibly unrelated) that causes it to stop working and users need to understand how it once worked. – Erty Seidohl Apr 24 '18 at 15:26
0

Maybe something like:

const rows = 3
const cols = 5

const nestedArray = new Array(rows).fill(0);

nestedArray.forEach((e, i, a) => a[i] = new Array(cols).fill(false));

console.log(nestedArray);
  • First, initialize the array with dummy values
  • Then, for each position initialize another nested array
Klaimmore
  • 680
  • 1
  • 6
  • 16
0

Quite similar to Ori Drori answer, but a little bit shorter :

const rows = 3;
const cols = 5;

const nestedArray = Array.from({length: rows}, () => Array(cols).fill(false));
nestedArray[1][2] = true;
console.log(nestedArray);
lavalade
  • 329
  • 2
  • 11