Using .forEach to solve "Diff two Arrays" Challenge

I was wondering if someone could help me understand this better. So for this challenge, I wrote the following:

function diffArray(arr1, arr2) {
  var newArr = [];
  // Same, same; but different.
  arr1.forEach(function(e1){
  	arr2.forEach(function(e2){
  		if(e1 !== e2){
  			newArr.push(e1 || e2);
  		}

  	})
  })
  console.log(newArr);
}

diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);

With the idea that it would go through each element of the array, and push to the new Array anything element that does not exist in both Arrays. However the output array ends up being:

[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 5, 5, 5, 5]

which is just the numbers that exist in both arrays, repeated four times. Can someone explain why this is the case?

If you add the following console.log statement right before the if statement, you will understand what is going on.

console.log('e1 = ' + e1 + ' e2 = ' + e2 + ' e1 !== e2 => '  + e1 !== e2);

So e1 !== e2 equates to true, alongside every other possible operator/argument combination?

It is not for all combinations. It is just for some of them.

newArr.push(e1 || e2);

The above will always push e1 into newArr, unless e1 is a falsey value.

Sorry, I don’t quite follow. So is the e1 !== e2 just checking if the value is true/false, instead of comparing the numbers/strings associated with it?

Now I’m extremely confused. I went a different route and tried using indexOf to compare the elements of the array in order to push any that don’t appear in both arrays to the new Array, but it seems to just register everything as true and push it to the array.

function diffArray(arr1, arr2) {
  var newArr = [];
  for( let i = 0; i < arr1.length; i++){
  	if (arr2.indexOf(arr1[i] === -1)){
  		newArr.push(arr1[i]);
  	}
  }
  console.log(newArr);
}

diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);
Output = [1,2,3,5,]

So I think this would be a useful time to walk through your code step by step and think about what each line is doing.

On the first line, you’re declaring a function called diffArray that takes two parameters - which at runtime will be assigned the variable names arr1 and arr2 respectively within the function scope.

Then, inside the function, you declare a variable called newArr that gets the value of an empty array.

Next, you declare a for loop. In the for loop’s scope, you declare a variable called i and set it equal to zero, and you tell the for loop to check the value of i against the aforementioned arr1's length property each “pass through the loop” as it were. Finally, the for loop, increments the value of i after each pass through the loop. The order in which these occur is important and occurs in a somewhat less than intuitive manner if you’re new to looping - you should read here about the for statement just to make sure you understand the order in which things are occurring in the loop.

The logic inside the for loop is the next line (at the if statement). In the if statement, you tell the interpreter to check the value of arr2.indexOf(arr1[i] === -1)). This is where I think you should really evaluate what you’re doing. In the arr2.indexOf() method, you’re passing an expression that will evaluate to a Boolean. So effectively, you’re going to get either arr2.indexOf(true) or arr2.indexOf(false), no matter what. You won’t be able to find an index of the value(s) true or false in the arrays being passed to your function. Additionally, if a matching value is not found, indexOf's return value is -1. It looks like you read the docs here, but your implementation is a little bit off

Finally, IF the if statement’s expression evaluates to a truthy value, you say: push to my variable newArr (which is an array, so push is appropriate here) the value arr1[i] --> (so if i = 1, you’d be pushing arr1[1] which evaluates to to 2, and so on…).

You might rewrite the code you have above as I’ve done here

That is a REALLY great tool for solving these sorts of problems, by the way. Play around with it, it let’s you step through every iteration of a loop and shows you all the values of all variables in scope. It really helped me nail down loops when I was first learning them.

careful with parenthesis…

Aha! It took me a while, but using that tool to see the execution of the code step by step helped me understand what the computer was doing, and where the code was falling apart.

function diffArray(arr1, arr2) {
  var newArr = [];

  for(let i = 0; i <arr1.length; i++){
  	if (arr1.indexOf(arr2[i]) === -1){
  		newArr.push(arr2[i])
  	}
  }
  console.log(newArr);


}


diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);

I’m not 100% there yet, but the code is now functional. Thank you for that really detailed response!