The best way I think to understand this is to log the iteration. Because the code is running a splice, it is mutating the array, i.e. it’s changing the data in it, and it’s doing so each loop. but the ‘i’ value, is increasing each loop. This won’t be an issue with filter as it’ll not change the array you’re working from, it’ll only return a new one. Look at the code below for a visualisation of a way to debug the problem and then the console logs of what the problem is:
function diffArray(arr1, arr2) {
let newArr = arr1.concat(arr2);
for (let i = 0; i < newArr.length; i++) {
if (arr1.includes(newArr[i]) && arr2.includes(newArr[i])) {
console.log('iteration:', i, 'arr:',newArr)
newArr.splice(i, 1);
}
}
return newArr;
}
Console logs:
iteration: 1 arr: [ 1, 2, 3, 5, 1, 2, 3, 4, 5 ]
iteration: 2 arr: [ 2, 3, 5, 1, 2, 3, 4, 5 ]
iteration: 3 arr: [ 2, 5, 1, 2, 3, 4, 5 ]
iteration: 4 arr: [ 2, 5, 2, 3, 4, 5 ]
iteration: 5 arr: [ 2, 5, 2, 4, 5 ]
[ 2, 5, 2, 4 ]
You can see because the data is mutating, the data being gone through is not being correctly searched by the code.
I can’t remember if FCC touches much on this but a good way to solve this problem would be with a Set
. They’re a nice way to remove duplicate values in code and then you could just search the original arrays with includes. It’s kind of similar to what I think you wanted to do for example:
function diffArray(arr1, arr2) {
const result = [];
const items = new Set([...arr1, ...arr2]);
//'spread' the arrays into one, basically make one array.
items.forEach(item=> {
//loop over the items in the set/unified array
if(!arr1.includes(item) || !arr2.includes(item)){
//if the current item/element in the loop is not in either original array we push it to the result variable
result.push(item);
}})
return result;
}
Here’s the MDN docs on Sets, definitely worth checking out :
Happy to answer any follow up questions, I hope that all made sense