'Filtering array objects with nested properties from another array objects properties in Javascript [closed]

I have 2 arrays structured like this :

const products = [
  {
    id: 1,
    name: 'Table',
    attributes: [
      { id: 13, prodId: 1, attribute_id: 1, attribute_value_id: 8 },
      { id: 14, prodId: 1, attribute_id: 2, attribute_value_id: 19 },
      { id: 15, prodId: 1, attribute_id: 3, attribute_value_id: 88 },
      { id: 16, prodId: 1, attribute_id: 4, attribute_value_id: 237 },
    ],
  },
  {
    id: 2,
    name: 'Chair',
    attributes: [
      { id: 25, prodId: 2, attribute_id: 1, attribute_value_id: 2 },
      { id: 26, prodId: 2, attribute_id: 2, attribute_value_id: 21 },
      { id: 27, prodId: 2, attribute_id: 3, attribute_value_id: 127 },
      { id: 28, prodId: 2, attribute_id: 4, attribute_value_id: 240 },
    ],
  },
  {
    id: 3,
    name: 'Couch',
    attributes: [
      { id: 41, prodId: 3, attribute_id: 1, attribute_value_id: 8 },
      { id: 42, prodId: 3, attribute_id: 2, attribute_value_id: 18 },
      { id: 43, prodId: 3, attribute_id: 3, attribute_value_id: 88 },
      { id: 44, prodId: 3, attribute_id: 5, attribute_value_id: 271 },
    ],
  },
  {
    id: 4,
    name: 'Rug',
    attributes: [
      { id: 75, prodId: 4, attribute_id: 1, attribute_value_id: 2 },
      { id: 76, prodId: 4, attribute_id: 2, attribute_value_id: 19 },
      { id: 77, prodId: 4, attribute_id: 3, attribute_value_id: 89 },
      { id: 78, prodId: 4, attribute_id: 4, attribute_value_id: 256 },
    ],
  },
]

const filters = [
  { attribute_id: 1, attribute_value_id: '8' },
  { attribute_id: 3, attribute_value_id: '88' },
]

How can I filter objects from the "products" array that matches at least all criteria from the "filters" array, no matter how many products are there, nor how many attributes each product has ?

In the above case, I would like to get the result :

[{
  id: 1,
  name: 'Table',
  attributes: [
    { id: 13, prodId: 1, attribute_id: 1, attribute_value_id: 8 },
    { id: 14, prodId: 1, attribute_id: 2, attribute_value_id: 19 },
    { id: 15, prodId: 1, attribute_id: 3, attribute_value_id: 88 },
    { id: 16, prodId: 1, attribute_id: 4, attribute_value_id: 237 },
  ],
},
{
  id: 3,
  name: 'Couch',
  attributes: [
    { id: 41, prodId: 3, attribute_id: 1, attribute_value_id: 8 },
    { id: 42, prodId: 3, attribute_id: 2, attribute_value_id: 18 },
    { id: 43, prodId: 3, attribute_id: 3, attribute_value_id: 88 },
    { id: 44, prodId: 3, attribute_id: 5, attribute_value_id: 271 },
  ],
}]

Edit : I've tried to start from something like this :

const filteredProducts = products.filter((p)=>{
    return filters.some((f)=>{
        // another loop ?
    });
});
console.log(filteredProducts);

but couldn't manage to loop through each product's nested attributes and through filters when there's many of them

NB : product "couch" having an attribute with "attribute_id" of 5 instead of 4 is not a typo

Hoping I'm clear enough, thanks in advance !



Sources

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

Source: Stack Overflow

Solution Source