Reputation: 39
I have a list
which could look like this:
let list = [
{
name: "Level 1",
children: [
{
name: "Level 2",
children: [
{
name: "Level 3A",
children: [],
},
{
name: "Level 3B",
children: [],
},
{
name: "Level 3C",
children: [],
},
],
},
],
},
];
As you can see it consists of elements with 2 properties: name
and children
.
This is simple list but it can be nested many levels down and each element could have a lot of children.
Moreover i have sample array of arrays of strings like this:
const filterRows = [
["Level 1", "Level 2", "Level 3A"],
["level 1", "Level 2", "Level 3C"]
]
Each of this 2 arrays of strings represents each 'row' in my list. (Here we don't have ["level 1", "Level 2", "Level 3B"]
)
My goal is to make something like filter. So based on filterRows
i want my list to be:
let filteredList = [
{
name: "Level 1",
children: [
{
name: "Level 2",
children: [
{
name: "Level 3A",
children: [],
},
{
name: "Level 3C",
children: [],
},
],
},
],
},
];
As you can see in filteredList
we only have rows specified in filterRows
(so here we don't have "Level 3B")
Could you help me create function to do that?
As i said list
(initial list) could be much more complicated I simplify it. Also filterRows
can be different (but always correctly represent some rows in our list
). So it cannot be hardcoded.
Upvotes: 0
Views: 538
Reputation: 386786
With matching strings, you could build a tree and rebuild the structure with the wanted items.
const
filter = level => (r, { name, children }) => {
const next = level[name];
if (next) {
if (Object.keys(next).length) children = children.reduce(filter(next), []);
r.push({ name, children });
}
return r;
},
list = [{ name: "Level 1", children: [{ name: "Level 2", children: [{ name: "Level 3A", children: [] }, { name: "Level 3B", children: [] }, { name: "Level 3C", children: [] }] }] }],
filterRows = [["Level 1", "Level 2", "Level 3A"], ["Level 1", "Level 2", "Level 3C"]],
tree = filterRows.reduce((r, a) => {
a.reduce((o, k) => o[k] ??= {}, r);
return r;
}, {}),
result = list.reduce(filter(tree), []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 2