Search code examples
javascriptarraystypescriptobject

How to filter array object based on array object


I have the original data array. How to filter array object based on the array object

const products = [
  {
    options: [
       { id: 1, name: 'Size', value: '10'},
       { id: 2, name: 'Color', value: 'yellow'},
    ],
  },
  {
    options: [
       { id: 1, name: 'Size', value: '20'},
       { id: 2, name: 'Color', value: 'yellow'},
    ],
  },
  {
    options: [
      { id: 1, name: 'Size', value: '10'},
      { id: 2, name: 'Color', value: 'pink'},
    ],
  },
  { 
    options: [
      { id: 1, name: 'Size', value: '20'},
      { id: 2, name: 'Color', value: 'pink'}
    ],
  },
  {
    options: [
      { id: 1, name: 'Size', value: '39'},
      { id: 2, name: 'Color', value: 'pink'},
    ],
   },
];

And a filter array object:

const conditions = [
  [
    { name: 'Size',value: '10'},
    { name: 'Color', value: 'yellow'},
  ],
  [
    { name: 'Size', value: '10'},
    { name: 'Color', value: 'pink'},
  ],
];

My expected output is:

const outputProducts = [
  {
    options: [
      { id: 1, name: 'Size', value: '10'},
      { id: 2, name: 'Color', value: 'yellow'},
    ],
  },
  {
    options: [
      { id: 1, name: 'Size', value: '10'},
      { id: 2, name: 'Color', value: 'pink'},
    ],
  },
];

Here is my code. Try with a filter then find and some function. But I don't know where is my mistake.

  const filterProducts = products.filter((el) => {
   return el.options.find((o) => {
     return conditions.find((m) => {
       return m.every(({ name, value }) => o.name == name && o.value === value);
     });
   });
 });

But did not get the correct result. Thank you!!


Solution

  • You try using the filter(), every(), and some() methods with arrow function syntax like the following way:

    const products = [
      {
        options: [
           { id: 1, name: 'Size', value: '10'},
           { id: 2, name: 'Color', value: 'yellow'},
        ],
      },
      {
        options: [
           { id: 1, name: 'Size', value: '20'},
           { id: 2, name: 'Color', value: 'yellow'},
        ],
      },
      {
        options: [
          { id: 1, name: 'Size', value: '10'},
          { id: 2, name: 'Color', value: 'pink'},
        ],
      },
      { 
        options: [
          { id: 1, name: 'Size', value: '20'},
          { id: 2, name: 'Color', value: 'pink'}
        ],
      },
      {
        options: [
          { id: 1, name: 'Size', value: '39'},
          { id: 2, name: 'Color', value: 'pink'},
        ],
       },
    ];
    
    const conditions = [
      [
        { name: 'Size',value: '10'},
        { name: 'Color', value: 'yellow'},
      ],
      [
        { name: 'Size', value: '10'},
        { name: 'Color', value: 'pink'},
      ],
    ];
    
    const filterProducts = products.filter(product =>
      //iterate over conditions to check if any of the conditions match the options of the current product
      conditions.some(condition =>
        //check if all the key-value pairs in each condition match the options of the current product
        condition.every(({ name, value }) =>
          //returns true if any of the conditions match, and the product is included in the result.
          product.options.some(option => option.name === name && option.value === value)
        )
      )
    );
    
    console.log(filterProducts);