# At the end of the second loop when i=1 why isn't newArray=[[0,0],[0,0,0,0]] and is [ [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] ] instead?

Tell us what’s happening:
Describe your issue in detail here.

``````  **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);
// console.log(row);
}
// Pushes the current row, which now has n zeroes in it, to the array
newArray.push(row);
console.log(newArray);
}
return newArray;
}
let cc=[[0,0]];
let bb=[0,0,0,0];
let dd=cc.push(bb);
let matrix = zeroArray(3, 2);
//console.log(matrix);
``````
``````  **Your browser information:**
``````

User Agent is: `Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36 OPR/76.0.4017.154`

Challenge: Use Caution When Reinitializing Variables Inside a Loop

Link to the challenge:

Because you didn’t reset row to `[ ]` before the ‘j’-loop, inside the ‘I’-loop.

``````for i-loop {
row = [];
for j-loop {
...
``````

I’m sorry I didn’t explain the problem well. I solved this challenge but I was looking at the initial code and was wondering why it was behaving the way it was behaving.

My understanding:

When i=0 j=0, row=
j=1,row=[0,0]
newArray={[0,0]]

I understand till here.

Now,

When i=1 j=0, row=[0,0,0]
j=1,row=[0,0,0,0]
Shouldn’t newArray be={[0,0],[0,0,0,0] ? That is shouldn’t it push the new row value of [0,0,0,0] to the previous value of newArray which was [[0,0]]?
Why is it [[0,0,0,0],[0,0,0,0]] instead?

I wanted to understand why the output is the way it is?

Because there’s exactly one array called `row` and you keep adding values to it. Array name is a reference, and your newArray is an array of the references to the same array. Here’s how it is working:

``````let row = [0,0];
let na = [];
na.push(row); //now na is [[0,0]]. It is like [row]

row.push(0); //now na is [[0,0,0]]. It is still [row] but row has changed

na.push(row); //now na is [[0,0,0], [0,0,0]]
row.push(0); //now na is [[0,0,0,0], [0,0,0,0]]
``````

Here’s an illustration: 2 Likes

Great explanation. Thank you so much. God bless you!

I have one more question do you know why the output is 2 here in this code instead of [[0,0],[0,0,0,0]] @twotani

``````let cc=[[0,0]];
let bb=[0,0,0,0];
let dd=cc.push(bb);
console.log(dd);
``````

Because the push method does not return an updated array. It returns the length of an updated array. You’ll get the array you expect if you do

``````let cc = ...
let bb = ...
cc.push(bb);
console.log(cc);
``````

In other languages, push indeed returns a new collection (array) but not in JavaScript.

1 Like

Thank you so much for the answer!

Can you please tell me what is wrong with my code. After much frustation I did look at the solution but I still wanted to see how I can fix it through this method.

``````function filteredArray(arr, elem) {
let newArr = [...arr];
// Only change code below this line
for(let i=0;i<arr.length;i++)
{
//console.log(i);
for(let j=0;j<arr[i].length;j++)
{
//console.log(arr[i][j]);

if((arr[i][j])==elem)
{

newArr.splice(i,1);

}
//console.log(arr[i]);

}

// newArr.push(arr[i]);

}
// Only change code above this line
return newArr;
}
console.log([["trumpets", 2], ["flutes", 4], ["saxophones", 2]]);
console.log(filteredArray([["trumpets", 2], ["flutes", 4], ["saxophones", 2]], 2) );
``````

as it is a new challenge, use the Ask for help button on that challenge to ask for help

ok I did can you please take a look if you can

I saw the other thread, too. I’ll reply here. When you have a question about specific challenge, you should use Get a Help link and so we know which challenge you’re referring to.

On a quick look, your solution seems to work, but the problem here is that the splice method modifies the array itself.

Initially `newArr` and `arr` are the same. When the first match is removed, newArr becomes

``````[ [ 'flutes', 4 ], [ 'saxophones', 2 ] ]
``````

Continuing, when` i` becomes 2 and found another match `['saxophones',2],` you execute

``````newArr.splice(i,1)
``````

i is 2 here, so you’re doing

``````newArr.splice(2,1)
``````

There is `arr` element but there’s no `newArr` element because `newArr` has already changed.

Your nested for loops will visit every nested elements of arr. You could change the logic from subtraction to addition. You start newArr to be an empty array. If you found a match (arr[i][j] == elem), you don’t add arr[i] to the answer (i.e., you jump out of j loop and continue). If none matches for all j of arr[i], then you add arr[i] to the answer.

1 Like

Thank you. I have been trying this since yesterday spent like 5 hours on this problem like tried addition, subtraction, starting out newArr to be an empty array, everything but couldn’t get it to work. If I do this, I get what needs to be removed. That is [ [ ‘trumpets’, 2 ], [ ‘saxophones’, 2 ] ] I had been trying since a couple of hours and it was driving me crazy how to switch to return an array that excludes this that is just [[ ‘flutes’, 4 ]]

`````` if((arr[i][j])==elem)
{

newArr.push(arr[i]);
break;

}
``````

can you help me out with a possible code.

How to implement this in code like where to put it.

Passed all tests except one with this code

``````function filteredArray(arr, elem) {
let newArr = [];
// Only change code below this line
for(let i=0;i<arr.length;i++)
{
//console.log(i);
for(let j=0;j<arr[i].length;j++)
{
//console.log(arr[i][j]);

if((arr[i][j])==elem)
{

i+=1;
break;

}

}
if(i<arr.length) newArr.push(arr[i]);

//console.log(arr[i]);

}

// newArr.push(arr[i]);

// Only change code above this line
return newArr;
}
console.log([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]]);
console.log(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3) );

``````

Its really good that you solved it on your own.

But you don’t want to change the value of index values like i and j inside the loop. This will potentially cause all sort of problem.

Let’s review. This logic is reverse

``````if((arr[i][j])==elem) {
newArr.push(arr[i]);
break;
}
``````

If you found a match, you do NOT want to add it. You corrected the logic by increment i by 1 and testing the condition after the j loop. You have the correct logic. Good. But the implementation technique is not so good (i.e., Do not forcefully change the loop variable inside its loop). The correct technique is to use a Boolean variable. This is a common technique and called a flag. You use a flag to record the condition. Using a flag, your code becomes

``````function filteredArray(arr, elem) {
let newArr = [];
let isFound = false;

for(let i=0;i<arr.length;i++)
{
isFound = false;  //IMPORTANT - reset the flag before nested loop

for(let j=0;j<arr[i].length;j++){
if(arr[i][j]==elem)
{
isFound = true; //element found; set the flag and exit the j loop
break;
}
}
if (!isFound) newArr.push(arr[I])
//check the flag
//if isFound is false (i.e. !isFound is true) then we exit the j loop
//by founding a match and breaking, so add it to the answer
//Otherwise, we exited the j loop normally without founding a match  so we do nothing
}

return newArr;
}
``````
2 Likes

Thank you so much for a detailed explanation! Freecodecamp didn’t teach about flags so I had no idea about it, but I will look into it. Thank you!

There are good tutorial sites out there you can check out for additional / alternative explanations and topics. Don’t rely on any single source as a be-all learning place.

Oh, I just noticed that you said “all tests passed except one.” That’s because there’s a situation that the test (i < arr.length) cannot distinguish the two conditions (found vs not found). It’s most likely due to the location of the found element in the array. Use of the boolean flag should make the code work 100%.

2 Likes thank you very much！