1

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"} ]

2 Answers 2

1

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

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

1 Comment

That made sense! I was thinking for over an hour why it behaves like that before asking and realizing that it was in fact because of the reference. Also in my second snippet, I realized that arr2 = [3, 4] doesn't change arr1 but arr2.push(3, 4) changes by appending. Thanks for the code and answer!
1

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

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.