Use Caution When Reinitializing Variables Inside a Loop- Unable to understand

Use Caution When Reinitializing Variables Inside a Loop- Unable to understand
0

Tell us what’s happening:
Hello Everyone,

I am unable to understand why we need to reinitialize the let row = []; inside the for loop to get the required result?

Please can anyone help me with this ?

Your code so far


function zeroArray(m, n) {
  // Creates a 2-D array with m rows and n columns of zeroes
  let newArray = [];
  let row = [];
  for (let i = 0; i < m; i++) {
    // Adds the m-th row into newArray
    
    for (let j = 0; j < n; j++) {
      // Pushes n zeroes into the current row to create the columns
      row.push(0);
    }
    // Pushes the current row, which now has n zeroes in it, to the array
    newArray.push(row);
  }
  return newArray;
}

let matrix = zeroArray(3, 2);
console.log(matrix);

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:67.0) Gecko/20100101 Firefox/67.0.

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/debugging/use-caution-when-reinitializing-variables-inside-a-loop

If you do not, row would contain 6 elements, when it should only ever contain 2 elements. You would have an array which looks like:

[
  [0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0]
}

instead of:

[
  [0, 0],
  [0, 0],
  [0, 0]
]

Thanks for your reply, please could you explain why we are getting the below array, I clearly understand what’s happening in that function, but unable to figure out why we are getting the below output.

[
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0]
]

Thanks once again.

Basically the following is what is happening during the various iterations:

push another 0 to row
now row is [0]
push another 0 to row
now row is [0,0]


push row to newArray
now newArray looks like below 
[ 
  [ 0, 0 ]
]

push another 0 to row
now row is [0,0,0]
push another 0 to row
now row is [0,0,0,0]

push row to newArray
now newArray looks like below 
[
  [ 0, 0, 0, 0 ],
  [ 0, 0, 0, 0 ] 
]

push another 0 to row
now row is [0,0,0,0,0]
push another 0 to row
now row is [0,0,0,0,0,0]

push row to newArray
now newArray looks like below 
[
  [ 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0 ]
]

You might be wondering why the final array does not look like below:

[
  [ 0, 0 ],
  [ 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0 ]
]

It is because row holds just a reference to a place in memory where the values of it are stored. Everytime you add a new element to row, you are really just adding the element to it’s reference. What this means is, everytime you pushed row into newArray, you were not pushing a new array. You were pushing the same array, so as row grew in size, newArr held 3 instances of this reference to the same array which was getting larger.

Another way to understand how arrays and objects are references is to look at the following code.

const arr = [1, 2, 3];

const anotherArr = arr;

anotherArr[1] = 'x' // change the value of the 2nd element of anotherArr to 'x'

console.log(anotherArr); // [1, 'x', 3];
console.log(arr) // [1, 'x', 3];

Since we assigned the arr to anotherArr, we were really just assigning the reference to the memory location which stores the actual values of the array. So when you changed the 2nd element of anotherArr, you were really just changing the value of the array referenced in memory.

Thank you so much I understand it, so each time you are pushing 0’s the global row is getting updated. Thanks

Also please could you explain how using let row = [ ]; inside the loop generates the below output?

[
  [0, 0],
  [0, 0],
  [0, 0]
]

If you put row = [] inside the loop, you are making row reference an empty array at the beginning of the iteration, then that empty array is being added elements, and then pushed to the other array.

And then at next iteration row is set again to reference an empty array…

And maybe you will ask why do all this work when we could just push trice row when it has two elements?
Well, we can’t actually, because if we want to change an element in the matrix we would change one element per row. Instead pushing three different arrays they are independent

Sorry I’m still unable to understand it, please could you explain it in somewhat briefly?

Is it because to make the let row = []; scope within the for loop, so that the newArray can’t use it as reference?

Look at what happens with this: http://pythontutor.com/javascript.html

Thank you I get it now. :grinning::grinning: