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
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=[0]
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]]
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) );
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[2] element but there’s no newArr[2] 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.
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 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;
}
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%.