5

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!

Carol.Kar
  • 4,581
  • 36
  • 131
  • 264
  • I'd do that by multiple `includes()` in filter with `||`, or something like this answer https://stackoverflow.com/questions/37896484/multiple-conditions-for-javascript-includes-method so you will create `contains` method which requires an array of possible values – Dominik Matis Aug 14 '19 at 17:12

5 Answers5

7

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));
Sash Sinha
  • 18,743
  • 3
  • 23
  • 40
4

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");
Bill
  • 1,407
  • 10
  • 18
4

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.

bitznbytez
  • 74
  • 1
  • 13
4

Check if the item is in the array instead

data = data.filter(cv => ["22", "234"].includes(cv.category));
baao
  • 71,625
  • 17
  • 143
  • 203
1

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.

John Franke
  • 1,444
  • 19
  • 23