I am currently trying to filter available products based on their selected options.
const products = [{
id: 1,
name: 'Safari',
horsepowers: 30,
doors: 4,
gear_type: 'automatic',
wheels: 6
},
{
id: 2,
name: 'Jungle',
horsepowers: 50,
doors: 3,
gear_type: 'automatic',
wheels: 5
},
{
id: 3,
name: 'Moon',
horsepowers: 30,
doors: 4,
gear_type: 'manual',
wheels: 4
}
]
const selectedOptions =
{
horsepowers: 50,
doors: 3,
gear_type: null,
wheels: null
}
Typically I would do something like
const availableProducts = products.filter((product) =>
product.horsepowers === selectedOptions.horsepowers &&
product.doors === selectedOptions.doors .... etc
however, how do I skip null values, empty arrays, and undefined values if the user has not yet selected all possible options yet?
>Solution :
The next provided approach takes advantage of the 2nd thisArg argument of almost every available prototypal array method.
Thus one can write a generic filter function which compares any item’s property values to the related ones configured by the selectedOptions object which will be passed alongside the filter function as filter‘s 2nd argument and as the filter function’s this context …
const selectedOptions = {
horsepowers: 50,
doors: 3,
gear_type: null,
wheels: null,
};
const products = [{
id: 1,
name: 'Safari',
horsepowers: 30,
doors: 4,
gear_type: 'automatic',
wheels: 6,
}, {
id: 2,
name: 'Jungle',
horsepowers: 50,
doors: 3,
gear_type: 'automatic',
wheels: 5,
}, {
id: 3,
name: 'Moon',
horsepowers: 30,
doors: 4,
gear_type: 'manual',
wheels: 4,
}];
function doItemPropertiesEqualEveryBoundSelectedOption(item) {
return Object
// create key value pairs from the `this` bound selected options.
.entries(this)
// skip/ignore selected option entries where `value` equals `null`.
.filter(([key, value]) => value !== null)
// execute item specific selected option validation via `every`.
.every(([key, value]) => item[key] === value);
}
console.log(
products
.filter(
doItemPropertiesEqualEveryBoundSelectedOption,
selectedOptions,
)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }