I have an object called cache
const cache = {
a: {
b: { c: [toRemove1, toPreserve1, toRemove2, toPreserve2], d: "irrelevant" }
}
}
This object is typed, so we would know exactly where to find the level for things to remove
and I want to filter out toRemove1
toRemove2
specifically on the level of c
, so we don't need to care about other levels in the cache
.
The filtered result is { a: { b: { c: [toPreserve1, toPreserve2] , d: 'irrelevant'} } }
The function I came up with is this
function filter(cache, thingsToRemove, mapper) {
const filtered = mapper(cache).filter(
(thing) => !thingsToRemove.includes(thing)
);
}
Here the mapper
is a function that traverses to the level where we want to perform the filtering. In this case it is (cache) => cache.a.b.c
Here is the problem, while my current solution does the job of filtering, I can't seem to preserve the original structure of the cache
, that means the result of mapper(cache).filter((thing) => !thingsToRemove.includes(thing))
is [toPreserve1, toPreserve2]
. But I need the returned object has the same structure as it was before.
Here is the live demo: https://codesandbox.io/s/still-feather-zuhcl?file=/src/index.js
I am not sure if it is possible with the current API.... if not, what should be changed?
Also I am well aware that we can pass another param to indicate where is the last property, in this case is c
. But I really would like to not need to explictly pass that param to achieve this.
I also know that I can add a path
to the API that takes an array of paths. e.g. ["a", "b", "c"]
But what I had in mind is to find a way to use a function to traverse it so that user of the API can rely on the type checking and auto complete rather than manually copy and paste the fields to form a path
array.