njpatten
njpatten

Reputation: 165

Filter array of objects based on values in second array

I have an array of objects that I'd like to filter to create a new array based on whether or not the value of any key matches any value in another array.

const array1 = [{name: 'pink', id: 13}, {name: 'orange', id: 17}, {name: 'red, id: 64}, {name: 'purple', id: 47}, {name: 'yellow', id: 23}, {name: 'gray', id: 2}, {name: 'black', id: 200}, {name: 'violet', id: 4}]

const array2 = ['red', 'blue', 'green', 'pink']

I've tried using a for...of loop inside of a return function but that is giving me errors.

    const array3 = array1.filter(color => {
        for (mainColor of array2){
            return color.name === mainColor 
        }
    });

This works but is clearly not the best way.

    const array3 = array1.filter(color => {
            return (color.main === 'red') || (color.main === 'blue')
        });

How can I get a third array from array1 that contains only the objects where the array1.name matches a value in array2?

Is it possible with ES6 or Lodash?

Thanks in advance!

Upvotes: 1

Views: 160

Answers (5)

trincot
trincot

Reputation: 351369

Let me give an alternative, that has slightly more code, but is more efficient as well, as it only needs to scan array2 once:

const array1 = [{name: 'pink', id: 13}, {name: 'orange', id: 17}, {name: 'red', id: 64}, {name: 'purple', id: 47}, {name: 'yellow', id: 23}, {name: 'gray', id: 2}, {name: 'black', id: 200}, {name: 'violet', id: 4}],
      array2 = ['red', 'blue', 'green', 'pink'];

const colorSet = new Set(array2),
      array3 = array1.filter(color => colorSet.has(color.name));

console.log(array3);

Upvotes: 3

connexo
connexo

Reputation: 56823

I know indexOf might seem a little outfashioned and ES5-ish, but it still does the job:

const array1 = [{name: 'pink', id: 13}, {name: 'orange', id: 17}, {name: 'red', id: 64}, {name: 'purple', id: 47}, {name: 'yellow', id: 23}, {name: 'gray', id: 2}, {name: 'black', id: 200}, {name: 'violet', id: 4}],
  array2 = ['red', 'blue', 'green', 'pink'];

let array3 = array1.filter(x => array2.indexOf(x.name) != -1)
console.log(array3)

Upvotes: 0

gurvinder372
gurvinder372

Reputation: 68443

Almost there, instead of for-loop use includes and return

const array3 = array1.filter(color => {
    return array2.includes ( color.name );
});

Or

const array3 = array1.filter( color => array2.includes ( color.name ) );

Upvotes: 4

Mamun
Mamun

Reputation: 68933

Try the following with Array's includes():

const array1 = [{name: 'pink', id: 13}, {name: 'orange', id: 17}, {name: 'red', id: 64}, {name: 'purple', id: 47}, {name: 'yellow', id: 23}, {name: 'gray', id: 2}, {name: 'black', id: 200}, {name: 'violet', id: 4}]

const array2 = ['red', 'blue', 'green', 'pink'];

const array3 = array1.filter(color => array2.includes(color.name));

console.log(array3);

Upvotes: 1

Alexis
Alexis

Reputation: 5831

The filter method already iterates on each item. You just have to return true if the element is present in the second array (by using indexOf or includes)

const array1 = [{name: 'pink', id: 13}, {name: 'orange', id: 17}, {name: 'red', id: 64}, {name: 'purple', id: 47}, {name: 'yellow', id: 23}, {name: 'gray', id: 2}, {name: 'black', id: 200}, {name: 'violet', id: 4}]

const array2 = ['red', 'blue', 'green', 'pink'];

let filteredArray = array1.filter(e => array2.indexOf(e.name) > -1);

console.log(filteredArray);

Upvotes: 0

Related Questions