&& vs || difference

&& vs ||:

I was stuck until i accidently changed the && with || and it worked… why did it? i was sure the && is the right operator


function diffArray(arr1, arr2) {
let arr = arr1.concat(arr2);
let newArr= arr.filter(num => !arr1.includes(num) || !arr2.includes(num))  
return newArr;
}

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

Challenge: Diff Two Arrays

Link to the challenge:

The two operators mean different things:
&& = AND
|| = OR

This line of code:

let newArr= arr.filter(num => !arr1.includes(num) || !arr2.includes(num))  

Basically means
“filter the arr, where the num is not included in arr1 or is not included in arr2”.
This breaks down to the numbers in arr being returned only if they aren’t included in either array.

So with your example code 4 is returned because that number is not included in one of the arrays (the first one).

If you replace || (OR) with && (AND) your logic then becomes:
“filter the arr, where the num is not included in arr1 and is not included in arr2”.

This breaks down to you will only return numbers that do not exist in either array, which will always return an empty array, as your filtering over the contents of a combination of both arrays, so its impossible for a number to be in the filter and not exist in both arrays

Now if you noticed I had to specify “not” a lot in my answer making things slightly confusing to read, so I want to point out a thing called De Morgan’s Law which essentially describes how you can transform a boolean algebra expression to a different form, while keeping its meaning.
Now at this point you might be extra confused, either by what I just said or if you opened that link and got even more confused with all the fancy notation. The core takeaway of De Morgan’s law for programming is you can remove ! from your code if your flip all ||s to &&s.

So to refactor your code you can change your code to:

function diffArray(arr1, arr2) {
  let arr = arr1.concat(arr2);
  let newArr= arr.filter(num => !(arr1.includes(num) && arr2.includes(num)))
  return newArr;
}

console.log(diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5])); // 4

The code now means:
“filter the arr, where the num is not included in arr1 and arr2”
This breaks down to the numbers in arr being returned if the number does not exist in one of the arrays. (this is the same behavior with ||, but the negation ! is “moved” out)

To make things extra clear, we can assign a well named variable :

function diffArray(arr1, arr2) {
  let arr = arr1.concat(arr2);
  let newArr= arr.filter(num => {
    const notInBothArrays =  !(arr1.includes(num) && arr2.includes(num));
    return notInBothArrays;
  })  
  return newArr;
}

console.log(diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5])); // 4

Corresponding codepen:
https://codepen.io/bradtaniguchi/pen/JjGEROj?editors=0012

4 Likes

thank you, that line made everything clear for me. apreciated