6

I want to be able to filter on multiple strings(types) in an array. For example I want to filter on type meat and type fruit in the data-structure below. What I want to achieve is a filtered data object.

const data = [{type: "meat", food: "hamburger"}, {type:"fruit", food:"banana"}, {type:"fish", food: "red snapper"}, {type:"vegetables", food:"fungi"}]

let filter1 = 'meat'
let filter2 = 'fruit'

const filteredData = data.filter( post => post.type.includes(filter1, filter2) ? post:'');

// My expected result after filtering: [{type: "meat", food: "hamburger"}, {type:"fruit", food:"banana"}]

Unfortunately it returns 4 results instead of the 2 as expected above.

I know how to deal with this in libraries like _underscore.js but I want to achieve it in modern EcmaScript.

0

1 Answer 1

11

Create an array of the types you want to include first, and then you can use an .includes test on that array. (Currently, your post.type.includes(filter1, filter2) doesn't work because includes only accepts one argument)

const data = [{type: "meat", food: "hamburger"}, {type:"fruit", food:"banana"}, {type:"fish", food: "red snapper"}, {type:"vegetables", food:"fungi"}]

let filter1 = 'meat'
let filter2 = 'fruit'

const filters = [filter1, filter2];

const filteredData = data.filter(({ type }) => filters.includes(type));
console.log(filteredData);

You could also use a Set for less runtime complexity

const data = [{type: "meat", food: "hamburger"}, {type:"fruit", food:"banana"}, {type:"fish", food: "red snapper"}, {type:"vegetables", food:"fungi"}]

let filter1 = 'meat'
let filter2 = 'fruit'

const filters = new Set([filter1, filter2]);

const filteredData = data.filter(({ type }) => filters.has(type));
console.log(filteredData);

Sign up to request clarification or add additional context in comments.

8 Comments

Thank you for these clear examples. Helped me a lot to understand this concept better. I have one more question; How to achieve this approach if you want to filter if each type consist of two instances, like type: {type: ["meat", "american"], food: hamburger}?
That'll be somewhat more complicated, iterate over the entries of the filter object and check if some of the values match (if array), or if the plain value matches (if string)
@CertainPerformance what if the strings inside 'filters' are in capital letters and we want to change them to lowerCase() first before matching with the 'type' in filter ?
@bubble-cord Change new Set([filter1, filter2]); to new Set([filter1, filter2].map(str => str.toLowerCase()));
@CertainPerformance How to change/check for lowerCase() inside the loop itself const filteredData = data.filter(({ type }) => filters.includes(type)); console.log(filteredData); ?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.