In my data object, there are multiple objects - optional with some dependency data. First I need to get all elements, with a given key (passed as string array). For this first step, the code is working to filter the give elements.
In the first step I filter two of five elements: one and two; and the expected result is ['@scope/one', '@scope/two'].
@scope/one has a deps key, so I need to add three and two also to the result. @scope/two is already existing in the result array.@scope/three has four as deps, which now also has to be added to the result.@scope/four has no deps, so the loop is finished.In this example the result should be ['@scope/one', '@scope/two', '@scope/three', '@scope/four'].
In other words: I need to filter for some elements and then I need to loop for each deps and add this key also to the result array.
const data = {
'@scope/one': { deps: { three: { foo: 'bar' }, two: { foo: 'bar' } } },
'@scope/two': { foo: 'bar' },
'@scope/three': { deps: { four: { foo: 'bar' } } },
'@scope/four': { foo: 'bar' },
'@scope/five': { foo: 'bar' },
};
function sanitize(data, whitelist) {
return whitelist.reduce(
(result, key) => (data[key] !== undefined ? Object.assign(result, { [key]: data[key] }) : result),
{}
);
}
const filtered = sanitize(data, ['one', 'two']);
const result = Object.keys(filtered);
console.log(result);
Maintain a queue of keys and keep pushing deps until the queue is empty:
function pick(obj, keys) {
let res = new Set(), queue = [...keys]
while (queue.length) {
let key = '@scope/' + queue.shift()
if (!res.has(key)) {
res.add(key)
let val = obj[key]
if (val.deps)
queue.push(...Object.keys(val.deps))
}
}
return [...res]
}
//
const data = {
'@scope/one': {deps: {three: {foo: 'bar'}, two: {foo: 'bar'}}},
'@scope/two': {foo: 'bar'},
'@scope/three': {deps: {four: {foo: 'bar'}}},
'@scope/four': {deps: {one: {foo: 'bar'}}}, // cycle!
'@scope/five': {foo: 'bar'},
};
console.log(pick(data, ['one', 'two']))
If circular dependencies are possible, add the if(!res.has(key)) check to break them.
As a side note, it would look more transparent if deps were just key lists rather than full objects.