I would like to filter an array given a filter object
function remove (array, filter) {
// magic
}
filter
is an object of variable size with any number of key/value
It should act as follows
const products = [
{ size: 'S', color: 'blue' },
{ size: 'L', color: 'red' },
{ size: 'S', color: 'red' },
{ size: 'L', color: 'green' },
]
// With a filter of keys/value it filters for the existing key/values
const filteredProducts1 = remove(products, { size: 'S', color: 'red' })
console.log(filteredProducts1)
/*
[
{ size: 'S', color: 'blue' },
{ size: 'L', color: 'red' },
{ size: 'L', color: 'green' },
]
*/
// With less key/value than the object array, it filters for the existing key/value
const filteredProducts2 = remove(products, { size: 'S' })
console.log(filteredProducts2)
/*
[
{ size: 'L', color: 'red' },
{ size: 'L', color: 'green' },
]
*/
// With more keys/values than the object array it discard the non-existing key/value
const filteredProducts1 = remove(products, { size: 'S', color: 'red', type: 'dress' })
console.log(filteredProducts1)
/*
[
{ size: 'S', color: 'blue' },
{ size: 'L', color: 'red' },
{ size: 'L', color: 'green' },
]
*/
My issue is in building a dynamic condition from the filter object
I’m trying to convert
{ key1: value1, key2: value2, ... , keyN: valueN }
into
condition 1 && condition2 && ... & conditionN
4
Answers
You can determine whether any key-value pair in the filter is present in each object in the array:
you can use
some
to return true if at least one of the conditions is exists and not equal to filter.you can even use
x[k]
instead ofx.hasOwnProperty(k)
if it is guaranteed that there will be keys which point to values with falsy values (undefined
,null
,0
..,''
).Also MDN recommends
Object.hasOwn
instead ofObject.hasOwnProperty
if your environment (browser/Node) supports it.edit
to fix the problem
now I’m filtering out the fields from the filter entries that are existing in the object to check and returning the whole array if the filter entries is empty
How about this, variable filters will return array of boolean of matching filter [true, false, true] etc. Then just return back array item if included false in filters variable
I think you are right on track, the key to solve your problem is to proper implement a function that can decide if an item should be removed or kept based on the key-values passed, and that should be able to handle dynamically your requirements.
Here is one suggestion for it:
A few notes about this implementation:
shouldkeep
is that it iterates over the keys of your filter object, and only returns true (which means "keep") if it passes through all the keys without fully matching valuesshouldkeep = kvs => obj =>
might seem weird, but it is actually very useful. It is called currying, and means you can apply one argument to the function and get back a function that expects the next argument. With this, you can do something likeproducts, {size: 'S'})
and it returns a function that you can use as a parameter tofilter
. Neat!