How to filter an array with another array

How to filter an array with another array
0

#1

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.


#2

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' ]

#3

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.


#4

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


#5

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.


#6

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.


#7

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' ]

#8

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!

#9

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


#10

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.


#11

Would you mind marking this thread Solved?