I don't Understand why the error is outputting what it is

Tell us what’s happening:
The code is adding 0s to the row array then pushing it to the newArray array with each loop.

The desired output is [[0,0],[0,0],[0,0]] and I understand that you either need to change the row variables scope or reset it after the 0s have been pushed to the newArray variable.

What I don’t understand is why the current erroneous code is outputting [[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0]] and not [[0,0],[0,0,0,0],[0,0,0,0,0,0]]. It’s adding the 0s to the new array after every loop so surely it’s adding 2 0s then 4 0s then 6 0s. Or am I missing something?

Thanks.

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 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15.

Challenge: Use Caution When Reinitializing Variables Inside a Loop

Link to the challenge:

try looking at the code with this tool:
http://pythontutor.com/javascript.html

this is what the challenge is trying to show you: arrays have this weird behaviour, they are passed by reference, that means that doing newArray.push(row); doesn’t add a copy of row to newArray, but a reference, so that any change to row is also reflected in newArray

Hello!

First things first… welcome to the forum :partying_face:! We hope you learn a lot.

Now, to the teaching

You’re, somewhat, correct.

The thing is that arrays in JavaScript are references, hence if the contents are modified those changes are reflected wherever the array is used.

To understand this you need to know what a reference is.

As you may know, whenever a program is executed its contents are stored in-memory (the RAM). This memory is like an array, where the values are stored with a reference to it. If you were using C++, you could print to the console the reference value and would get something like 0x000adec0 (which would be the address in memory).

So, when you create an array, you store the reference in the variable. Each assignment of the array to a new variable is just a reference to that same memory space (the reference).

Now, if we go back to the code, this line:

newArray.push(row);

Is assigning the reference to row as a new element of the newArray.

You can try it yourself :slight_smile:. Add something like this to the end of code (after the last console.log):

matrix[1][0] = 30;
console.log(matrix);

and see what happens :open_mouth:.

1 Like

Thank you so much, this has really cleared things up. I’ve also responded to the response above and just have a few more questions:

So when I put row = after newArray.push(row) is that creating a new version of row somewhere else in the memory and therefore by the end of the loop we have three versions of row = [0,0]? Also if we change the scope of row, it still looks like it’s creating 3 versions of row in different points in the memory, why is that?

Thanks!

Thank you so much, that tool was really helpful. Essentially the newArray becomes [row, row, row] with row being a ‘pointer’ to where row is stored in memory and all change when row is changed.

So when I put row = after newArray.push(row) is that creating a new version of row somewhere else in the memory and therefore by the end of the loop we have three versions of row = [0,0]? Also if we change the scope of row, it still looks like it’s creating 3 versions of row in different points in the memory, why is that?

Sorry if my explanations aren’t clear, still coming to terms with a lot of the terminology.

when you do that you create a new array, and assign that array to the row variable, the array of before still exist, so when it was used it stay there, but can’t be referenced anymore with row

because inside different scopes you can create different variables with the same name, which point to different variables
each iteration of the loop is a different scope
also whenever you use [] you are creating a new array, never used before, so a new array is created each time there is a let row = [] line

1 Like

Is it clear now or still with questions :slight_smile:?

1 Like

all clear thank you!

1 Like