How to filter an array with another array

I have done a bit of research on this topic, but I am still confused about the best way to filter an array with another array. There are two scenarios I would like to understand better. (1) The second array remains intact after filtering the first array.

For example:
Input:
array1 = [a, b, c, d, e]
array2 = [b, d, f]

Output:
array1 = [a, c, e]
array2 = [b, d, f]

(2) The second array loses the elements that it used to filter the first array.

For example:
Input:
array1 = [a, b, c, d, e]
array2 = [b, d, f]

Output:
array1 = [a, c, e]
array2 = [f]

Thank you for the help.

For the 1st example, you could do something like:

``````var array1 = ['a', 'b', 'c', 'd', 'e'];
var array2 = ['b', 'd', 'f'];

array1 = array1.filter(function(item) {
return !array2.includes(item);
})
console.log(array1); // [ 'a', 'c', 'e' ]
console.log(array2); // [ 'b', 'd', 'f' ]
``````

For the 2nd example, you could do something like:

``````var array1 = ['a', 'b', 'c', 'd', 'e'];
var array2 = ['b', 'd', 'f'];

var tempArr = array2.filter(function(item) {
return !array1.includes(item);
});
array1 = array1.filter(function(item) {
return !array2.includes(item);
});
array2 = tempArr;

console.log(array1); // [ 'a', 'c', 'e' ]
console.log(array2); // [ 'f' ]
``````

Another solution for the 2nd example (not as efficient for large arrays because of what splice does behind the scenes), but looks cleaner:

``````var array1 = ['a', 'b', 'c', 'd', 'e'];
var array2 = ['b', 'd', 'f'];

array2 = array2.filter(function(item) {
return !array1.includes(item) ? true : array1.splice(array1.indexOf(item),1) && false;
});

console.log(array1); // [ 'a', 'c', 'e' ]
console.log(array2); // [ 'f' ]
``````
1 Like

I dont want to give you a full solution but for #2 part one you can do something like this

``````function blah(){
return array1.filter((char) => {
return array2.indexOf(char) === -1;
});
});
``````

Array.indexOf() will return the index of the item in the array if it is present. If it is not it will return -1.

Also make sure you understand what filter is doingβ¦ Array.filter() returns a new array containing all the items that evaluate to βtrueβ based on some criteria (ie whatever your callback function specifies). So in my example the code βsaysβ Filter array1 down to only contain the values that are not in array2 etc.

1 Like

In the second solution you gave for example two, does `false` trigger `filter` to remove `'b'` and `'d'` from array2?

Actually, because !array1.includes(item) evaluates to true in the filter, βbβ, and βdβ are removed from array2. (The first example of solution #2 does the same thing). This statement is basically asking Is item NOT in array1? Because item is representative of array2βs elements, βfβ is the only element of array1 not in array2, so βfβ is the only thing assigned to array2 in the item in this example array2.

The second example of the second solution appears more complicated until you understand how:

1. tenary operators work
2. how filter works
3. how splice works

For now, think of this 2nd example as a more advanced solution that you will learn to understand as you master how to use these above concepts/functions.

Let me make sure I understand the code (approximately). I have yet to acquire the proper lingo for discussing it.

``````var array1 = ['a', 'b', 'c', 'd', 'e'];
var array2 = ['b', 'd', 'f'];

array2 = array2.filter(function(item) {
return !array1.includes(item) ? true : array1.splice(array1.indexOf(item),1) && false;
});

console.log(array1); // [ 'a', 'c', 'e' ]
console.log(array2); // [ 'f' ]
``````

is given the following conditions:

1. If the item in array2 is not already in array1, the function should return βtrueβ and array2 is left unmodified.
2. If the item in array2 is already in array1, the function should return βfalseβ and the index of the item in array1 should be located and the item removed.

In this case, two of the items in array2 (βbβ and βdβ) are already in array1, so for them βfalseβ is returned and the accompanying action is carried out (βbβ and βdβ are spliced out of array1). Item βfβ is not already in array1, so βtrueβ is returned and no action is carried out.

Remember that filter returns a new array and does not modify the original. The only reason array2 is modified is because I assign the new array created from the filter back to array2.

Let me re-write the example 2 of solution 2 below, so we take the whole tenary operator out of the solution. See my comments in the code for what is happening.

``````var array1 = ['a', 'b', 'c', 'd', 'e'];
var array2 = ['b', 'd', 'f'];

array2 = array2.filter(function(item) {
if (!array1.includes(item)) {
return true; // this part is creating ['f'] which will be re-assigned to array2 when finished
}
else {
array1.splice(array1.indexOf(item),1); // this part is modifying array1 to be ['a','c','e']
return false;
}
});

console.log(array1); // [ 'a', 'c', 'e' ]
console.log(array2); // [ 'f' ]
``````
1 Like

I am playing around with the function to understand how ternary operators work. Can you correct me where I am wrong?

Example 1:

``````var array1 = ['a', 'b', 'c', 'd', 'e'];
var array2 = ['b', 'd', 'f'];

array2 = array2.filter(function(item) {
return !array1.includes(item) ? true : false;
});

console.log(array1); // [ 'a', 'b', 'c', 'd', 'e' ]
console.log(array2); // [ 'f' ]
``````

Conditions:

1. If array1 does not include an item from array2, the function returns true, and a new array containing the item is created. This new array is assigned to array2. In the example above, when we call array2, we now get `[ 'f' ]` and not `['b', 'd', 'f']`.
2. If array1 already includes an item from array2, the function returns false. In this case, there is no accompanying action to be carried out.

Example 2:

``````var array1 = ['a', 'b', 'c', 'd', 'e'];
var array2 = ['b', 'd', 'f'];

array2 = array2.filter(function(item) {
return array1.includes(item) ? true : false;
});

console.log(array1); // [ 'a', 'b', 'c', 'd', 'e' ]
console.log(array2); // [ 'b', 'd' ]
``````

Conditions:

1. If array1 includes an item from array2, the function returns true, and a new array containing the item is created. This new array is assigned to array2. In the example above, when we call array2, we now get `[ 'b', 'd' ]` instead of `['b', 'd', 'f']`.
2. If array1 does not include an item from array2, the function returns false. In this example, no accompanying action is carried out. Aha!

I just read your last message. Let me modify the last examples I gave.

Okay.

``````  if (!array1.includes(item)) {
return true; // this part is creating ['f'] which will be re-assigned to array2 when finished
}
``````

Got it.

``````  else {
array1.splice(array1.indexOf(item),1); // this part is modifying array1 to be ['a','c','e']
return false;
``````

Got it.
It makes more sense now.

Would you mind marking this thread Solved?