'Filter array on multiple attributes on same key

I have a json and would like to filter for one key multiple attribites as exact match.

I tried the following:

let data = [{
  "name": "Product 2",
  "link": "/stock/product2",
  "category": "234",
  "description": ""
}, {
  "name": "Product 1",
  "link": "/stock/product1",
  "category": "1231",
  "description": ""
}, {
  "name": "Product 3",
  "link": null,
  "category": "22",
  "description": ""
}]

data = data.filter(cv => cv.category === ["22", "234"]);

console.log(JSON.stringify(data))

I would like to get back the object with the name: Product 2 and name: Product 3.

Any suggestions why I get [] back?

I appreciate your replies!



Solution 1:[1]

Consider using Set.has for your desired attributes, so you can can have O(1) lookup time rather than the O(n) (where n is the number of desired attributes) lookup time using Array.includes.

As a result, if you use a set the overall the time complexity for the whole filter line will be O(m) (where m is the number of objects in data) rather than O(mn) if you used Array.includes or had multiple if-else / or conditions to check for each desired attribute:

const data = [
  {
    name: "Product 2",
    link: "/stock/product2",
    category: "234",
    description: "",
  },
  {
    name: "Product 1",
    link: "/stock/product1",
    category: "1231",
    description: "",
  },
  {
    name: "Product 3",
    link: null,
    category: "22",
    description: "",
  },
];

const desiredCategories = new Set(["22", "234"]);

const filteredData = data.filter(cv => desiredCategories.has(cv.category));

console.log(JSON.stringify(filteredData, null, 2));

Solution 2:[2]

You are comparing a single value against an array of values. One solution would be to check for one value or (||) the other.

data = data.filter(cv => cv.category === "22" || cv.category === "234");

Solution 3:[3]

This can be achieved by the includes method.

let data = [{
  "name": "Product 2",
  "link": "/stock/product2",
  "category": "234",
  "description": ""
}, {
  "name": "Product 1",
  "link": "/stock/product1",
  "category": "1231",
  "description": ""
}, {
  "name": "Product 3",
  "link": null,
  "category": "22",
  "description": ""
}]

data = data.filter(cv => ["22", "234"].includes(cv.category));

console.log(JSON.stringify(data))

Besides, I think this is easy to read/understand.

Solution 4:[4]

Check if the item is in the array instead

data = data.filter(cv => ["22", "234"].includes(cv.category));

Solution 5:[5]

const data = [{
  "name": "Product 2",
  "link": "/stock/product2",
  "category": "234",
  "description": ""
}, {
  "name": "Product 1",
  "link": "/stock/product1",
  "category": "1231",
  "description": ""
}, {
  "name": "Product 3",
  "link": null,
  "category": "22",
  "description": ""
}]

const filteredData = data.filter(({ category }) => category === "22" || category === "234");

console.log(JSON.stringify(filteredData))

I wouldn't mutate your original object. Also, you can deconstruct category in the filter function.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Bill
Solution 3 bitznbytez
Solution 4 baao
Solution 5