Explanation needed for "Use Caution When Reinitializing Variables Inside a Loop"

Explanation needed for "Use Caution When Reinitializing Variables Inside a Loop"
0

#1

I’m having difficulty understanding the logic of this exercise and why we need to move the empty row array from outside the loop to inside the outer loop. I read draber06’s explanation, however it still doesn’t make complete sense to me. Here is what he wrote:

Problem is that row never resets. Arrays and objects act as pointers in JavaScript. When you push row into the matrix array, you are pushing a pointer to row into the matrix array, not a copy of row at that point in time. The next time you change row by pushing a 0 onto it, the row already in the matrix array changes too. That’s because matrix[0] is a pointer to a location in memory, and when you call row.push(0), you are changing that location in memory. Therefore the next time you call matrix[0] it will include all changes you’ve made.
You’ll find that matrix[0] === matrix[1]. Same is true for matrix[2]. They are all three pointers to the same location in memory (row).
To solve this, you want to put your row = [] inside the first for loop. This tells it to make a new row (or a new location in memory) every iteration.
If you want to get your expected outcome of 2 columns, 4 columns, 6 columns, then instead of pushing row to matrix, push row.slice(0). This pushes a copy of row to matrix, meaning that all subsequent changes to row will not affect the copy that you pushed. That is, matrix will not contain a pointer to row, but a pointer to a copy of row at some point in time.

I’d really appreciate if someone could break it down in somewhat different terms to make it more comprehensible to me, or link to an article somewhere that goes into this issue at a slower pace and in perhaps more detail.

This is quite an important topic because I know that later challenges in the intermediate algorithms section will make use of problems similar to this one.


#2

can you add a link to this exercise?


#3

Which part of @draber06’s explanation do you not understand?

In the future, please post the url of the challenge, so other users do not have to search and find it.

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


#4

The entire explanation I found to be simply too confusing, even after reading it over many, many times.

That’s why I asked if someone could explain it in different terms, or in a different format, etc.


#5

OK, I will try to explain why you must move the empty row array to be inside the outer loop.

You want the final array (newArray) to be an array of arrays. Not only that, but you want newArray to only contain m number of sub arrays which have a length of n.

If you leave leave the let row = [] outside the outer loop, then row keeps growing beyond the n number length each row array should have.

Sometimes it is best to see using console.log statements.

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++) {
    console.log('i = ' + i);
    console.log('row starts as ' + JSON.stringify(row));
    // 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);
    }
   console.log('after pushing values to row, row is ' +  JSON.stringify(row));
    // 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);

Running the above code, produces the following in the browser’s console.

i = 0
row starts as []
after pushing values to row, row is [0,0]
i = 1
row starts as [0,0]
after pushing values to row, row is [0,0,0,0]
i = 2
row starts as [0,0,0,0]
after pushing values to row, row is [0,0,0,0,0,0]
[ [ 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0 ] ]

If you move the empty array declaration inside the outer for loop, the console would look like:

i = 0
row starts as []
after pushing values to row, row is [0,0]
i = 1
row starts as []
after pushing values to row, row is [0,0]
i = 2
row starts as []
after pushing values to row, row is [0,0]
[ [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ]


#6

Thanks, that made it a little bit clearer.