im using for to assign a value to an array but when I print the array it just shoes the last value in the full array

Viewed 58

I created an array using the array class with size of 8 * 8 and filling it with a dumy object using fill . and after that I created a for and assigning the values . but when I print the array . the same value is there for all the field .

var gridSize = 8;
    const colorname = ["Red", "Orange", "Green", "Blue", "Purple", "Yellow"];

var gameGrid = new Array(gridSize * gridSize).fill({
        loc: null,
        color: null,
        index: null,
        value: null
    });
fillTheGrid();

function fillTheGrid() {
        for (var i = 0; i < gridSize * gridSize; i++) {
            addElement(i)
        }
}


// actual code Is big so im using I for index and value 
function addElement(i){
        gameGrid[i].loc = i;
        let randomColor = Math.floor(Math.random() * colorname.length);
        gameGrid[i].color = colorname[randomColor];
        gameGrid[i].index = i;
        gameGrid[i].value = i;
}

log(gameGrid);

expected output is

[{"loc":1,"color":"Green","index":1,"value":1},{"loc":2,"color":"Red","index":2,"value":2},......,{"loc":63,"color":"Green","index":63,"value":63}]

but im getting

[{"loc":63,"color":"Green","index":63,"value":63},...,{"loc":63,"color":"Green","index":63,"value":63}]

that is im getting same value for all

2 Answers

In JS objects are passed by reference, so when you do

var gameGrid = new Array(gridSize * gridSize).fill({
    loc: null,
    color: null,
    index: null,
    value: null
});

the same object is put in each spot - if you update any of them, you update "all" of them. What you need to do is put a different object in each spot by doing:

var gameGrid = new Array(gridSize * gridSize).fill(null).map(i => ({
    loc: null,
    color: null,
    index: null,
    value: null
});

var gridSize = 8;
    const colorname = ["Red", "Orange", "Green", "Blue", "Purple", "Yellow"];

var gameGrid = new Array(gridSize * gridSize).fill(null).map(i => ({
        loc: null,
        color: null,
        index: null,
        value: null
    }));
fillTheGrid();

function fillTheGrid() {
        for (var i = 0; i < gridSize * gridSize; i++) {
            addElement(i)
        }
}


// actual code Is big so im using I for index and value 
function addElement(i){
        gameGrid[i].loc = i;
        let randomColor = Math.floor(Math.random() * colorname.length);
        gameGrid[i].color = colorname[randomColor];
        gameGrid[i].index = i;
        gameGrid[i].value = i;
}

console.log(gameGrid);

If you look at the description of Array.prototype.fill() method on MDN, it says:

If the first parameter is an object, each slot in the array will reference that object

So unlike you expected, there is only one object in memory and each slot in the array is referencing that same object.

Following code snippet demonstrates this behavior

let arr = Array(3).fill({});
arr[0].a = "hello";

arr.forEach(obj => console.log(obj));

Solution:

There is no need to initially fill the array with objects, you could just create a new object each time addElement() function, add key-value pairs in the newly created object and add this object in the array.

var gridSize = 8;
const colorname = ['Red', 'Orange', 'Green', 'Blue', 'Purple', 'Yellow'];

var gameGrid = new Array(gridSize * gridSize).fill(null);
fillTheGrid();

function fillTheGrid() {
  for (var i = 0; i < gridSize * gridSize; i++) {
    addElement(i);
  }
}

function addElement(i) {
  const obj = {};
  obj.loc = i;
  let randomColor = Math.floor(Math.random() * colorname.length);
  obj.color = colorname[randomColor];
  obj.index = i;
  obj.value = i;
  
  gameGrid[i] = obj;
}

console.log(gameGrid);

Related