-1

Basically I'm trying to figure out the cleanest way to select one item from an array, only if all certain values exist.

const filterValues = ['blue', '30cm', 'true'];

const products = [
{
  details: [
    { id: 1, value: 'red' },
    { id: 2, value: '30cm' },
    { id: 3, value: 'true' },
    { id: 4, value: '123432'}
  ],
  name: "Product 1"
},
{
  details: [
    { id: 5, value: 'blue' },
    { id: 6, value: '30cm' },
    { id: 7, value: 'true' },
    { id: 8, value: '98348'}
  ],
  name: "Product 2"
},
{
  details: [
    { id: 9, value: 'black' },
    { id: 10, value: '40cm' },
    { id: 11, value: 'false' },
    { id: 12, value: '578347'}
  ],
  name: "Product 3"
},
]

Only Product 2 contains all the filter values, so I want to return that product.

I have tried:

products.filter(p => {
  p.details.find(k => filterValues.includes(k.value));
})

but this returns if any of the values satisfies the condition rather than if all of them are included. This is the main issue here. I'm struggling with finding a way to filter if only all these values int he array are present in the object.

tcurtis
  • 25
  • 5
  • So what exactly are you struggling with; what’s the question? Sounds like a simple `filter` or `find` function using some logical operators and knowing [how to access and process nested objects, arrays or JSON](https://stackoverflow.com/q/11922383/4642212). – Sebastian Simon Feb 09 '21 at 15:21
  • 2
    What have you tried so far? – NullDev Feb 09 '21 at 15:21
  • I remember when people tried this kind stuff using a loop – GetSet Feb 09 '21 at 15:28
  • @SebastianSimon I added a bit more of a description – tcurtis Feb 09 '21 at 15:29
  • Let's suppose you were struggling with the filter method. Any reason why you just didnt go the long way and write a loop with if conditions @tcurtis? – GetSet Feb 09 '21 at 15:35
  • @GetSet I'd like to become more familiar with using the filter method or if there is another approach with array methods that I am unfamiliar with – tcurtis Feb 09 '21 at 15:37
  • Becoming familiar with iterating an array via a loop will give inherent insight to any helper method that does the same via callbacks – GetSet Feb 09 '21 at 15:38
  • But you probably got downvoted because this question type has numerous examples all over the internet. All you did here was present your non working code attempt – GetSet Feb 09 '21 at 15:40
  • @tcurtis Your arrow function in `filter` does not return anything if you leave the curly brackets there. Get familiar with arrow function syntax. [Documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), [When should I use a return statement in ES6 arrow functions](https://stackoverflow.com/q/28889450/4642212). – Sebastian Simon Feb 09 '21 at 15:44

1 Answers1

1

Use Array#every.

const filterValues = ['blue', '30cm', 'true'];

const products = [
{
  details: [
    { id: 1, value: 'red' },
    { id: 2, value: '30cm' },
    { id: 3, value: 'true' },
    { id: 4, value: '123432'}
  ],
  name: "Product 1"
},
{
  details: [
    { id: 5, value: 'blue' },
    { id: 6, value: '30cm' },
    { id: 7, value: 'true' },
    { id: 8, value: '98348'}
  ],
  name: "Product 2"
},
{
  details: [
    { id: 9, value: 'black' },
    { id: 10, value: '40cm' },
    { id: 11, value: 'false' },
    { id: 12, value: '578347'}
  ],
  name: "Product 3"
},
]

console.log(products.filter(p => filterValues.every(fv => p.details.map(d => d.value).includes(fv))));
h0ly
  • 76
  • 7