Nugget
Nugget

Reputation: 81

Javascript array.push replaces all elements instead of adding an array

I was just trying stuff out in Vanilla JS and ran into a problem where array.push does not push another array (row) whose elems got changed in a for loop, but rather replaces the whole array (mainArr). It would be better to show the code so please scroll below

function genArray(m, n) {
  let mainArr = [];
  let row = [];
  for (let i = 0; i < m; i++) {
    for (let j = 0; j < n; j++) {
        row.push(j);
    }
    mainArr.push(row)
  }
  return mainArr;
}
let myArr = genArray(3, 2);
console.log(myArr);
/**
 * outputs:
 * 
 * [ [ 0, 1, 0, 1, 0, 1 ],
 *   [ 0, 1, 0, 1, 0, 1 ],
 *   [ 0, 1, 0, 1, 0, 1 ] ]
 * 
 * why not:
 * 
 * [ [ 0, 1 ], 
 *   [ 0, 1, 0, 1 ], 
 *   [ 0, 1, 0, 1, 0, 1 ] ]
 */

At first I thought it was just because of the reference being appended as this SOF answers says, but as the code shows it doesn't.

let arr1 = []
let arr2 = [1, 2]
arr1.push(arr2)
console.log(arr1); // [ [ 1, 2 ] ]
arr2 = [2, 4]
console.log(arr1); // still [ [ 1, 2 ] ]

let arr3 = []
let obj1 = {name: "John"}
arr3.push(obj1)
console.log(arr3); // [ {name: "John"}]
obj1.name = "Mike"
console.log(arr3); // [ {name: "Mike"} ]

Upvotes: 1

Views: 2048

Answers (2)

Feras Tamesh
Feras Tamesh

Reputation: 21

You can use Destructuring assignment instead of array.push. just like this:

  function genArray(m, n) {
    let mainArr = [];
    let row = [];
    for (let i = 0; i < m; i++) {
      for (let j = 0; j < n; j++) {
        row=[...row,j];
      }
      mainArr.push(row)
    }
    return mainArr;
  }
  let myArr = genArray(3, 2);
  console.log(myArr);

Upvotes: 1

Majed Badawi
Majed Badawi

Reputation: 28414

You are updating the same array every time, so all inserted lists will eventually point to the same reference with the value set in the last iteration.

The following is a fix with an enhancement to reach the expected output:

function genArray(m, n) {
  const mainArr = [];
  for (let i = 0; i < m; i++) {
    const row = [];
    let count = i;
    while(count-- >= 0) {
      for (let j = 0; j < n; j++) {
        row.push(j);
      }
    }
    mainArr.push(row)
  }
  return mainArr;
}

console.log( genArray(3, 2) );

Upvotes: 1

Related Questions