1

I'm trying to create a nxn chessboard in single line of code using Array.fill like

let  board = new Array(n).fill(new Array(n).fill('O')); 

when i try to modify the first square like board[0][0] = 'Q'.It's changing all the 0th index elements all n sub arrays. My intention is

┌─────────┬─────┬─────┬─────┬─────┐
│ (index) │  0  │  1  │  2  │  3  │
├─────────┼─────┼─────┼─────┼─────┤
│    0    │ 'Q' │ 'O' │ 'O' │ 'O' │
│    1    │ 'O' │ 'O' │ 'O' │ 'O' │
│    2    │ 'O' │ 'O' │ 'O' │ 'O' │
│    3    │ 'O' │ 'O' │ 'O' │ 'O' │
└─────────┴─────┴─────┴─────┴─────┘

But when i do board[0][0] = 'Q'

┌─────────┬─────┬─────┬─────┬─────┐
│ (index) │  0  │  1  │  2  │  3  │
├─────────┼─────┼─────┼─────┼─────┤
│    0    │ 'Q' │ 'O' │ 'O' │ 'O' │
│    1    │ 'Q' │ 'O' │ 'O' │ 'O' │
│    2    │ 'Q' │ 'O' │ 'O' │ 'O' │
│    3    │ 'Q' │ 'O' │ 'O' │ 'O' │
└─────────┴─────┴─────┴─────┴─────┘

But it works as expected, when i'm creating array like this

let board = [
  ['O','O','O','O'],
  ['O','O','O','O'],
  ['O','O','O','O'],
  ['O','O','O','O'],
]

  • 1
    fill copies the same reference to all elements. You will have to map on it – user120242 Jun 21 '20 at 04:37
  • 1
    `Array(n).fill().map(_ => Array(n).fill('O'));` should work. The parameter to `fill` is always aliased. – ggorlen Jun 21 '20 at 04:41
  • 2
    Does this answer your question? [Array.prototype.fill() with object passes reference and not new instance](https://stackoverflow.com/questions/35578478/array-prototype-fill-with-object-passes-reference-and-not-new-instance) – user120242 Jun 21 '20 at 04:42

2 Answers2

0

Try this:

n = 4
let toFill = 'O'

let board = new Array(n);
for(let i = 0; i < n; i++){
    board[i] = ((new Array(n)).fill(toFill))
}

console.log(board);

output:

[
  [ 'O', 'O', 'O', 'O' ],
  [ 'O', 'O', 'O', 'O' ],
  [ 'O', 'O', 'O', 'O' ],
  [ 'O', 'O', 'O', 'O' ]
]
mipsc
  • 113
  • 7
0

You're filling the single value to the array items

way to do this:

const getGrid = n => Array.from({ length:n }).map(() => new Array(n).fill(0))

Here's why.

While doing new Array(n), it constructs an array whose length is n, and by calling fill prototype function and pass an value, it just equals to this:

const array = new Array(n);
const someObject = {}; // or [], or new Array(n).fill(0), the same

array[0] = someObject;
array[1] = someObject;
//...
array[n-1] = someObject

as all items are pointing to single one object, so while you are modifying the first item, you are operating the someObject, and you may see all item changes. So only way to do this is while filling second-level array to first, you cannot use fill function.

Another tip

About Array.from({ length:n }) and new Array(n),by calling new Array(n) you are creating an array with all items being empty, the array is known as sparse matrix, you cannot use .map(()=>{}) to fill it. but Array.from({length:n}) will create an array with undefined as items, which can be mapped to other values.

You may want these as reference:

is-javascript-a-pass-by-reference-or-pass-by-value-language

javascript-primitive-vs-reference-values

whats-the-difference-between-empty-items-in-a-javascript-array-and-undefined

Oboo Cheng
  • 4,250
  • 3
  • 24
  • 29