Reputation: 187
I have an array of objects with children. The goal is to remove every item from items arrays.
Is it possible to do without using forEach and map loops? How to use reduce in this case?
The problem is some arrays have items on one level and others have children array with items inside. Sample here:
{
"label": "child1",
"children": [
{
"label": "child2",
"items": [
"item1",
"item2"
]
},
{
"label": "child3",
"items": [
"item1",
"item2",
"item3"
]
}
]
}
As a result, I want to see a mutated array of objects with empty items arrays. Here`s an object to be mutated:
[
{
"label": "parent",
"children": [
{
"label": "child1",
"children": [
{
"label": "child2",
"items": [
"item1",
"item2"
]
},
{
"label": "child3",
"items": [
"item1",
"item2",
"item3"
]
}
]
},
{
"label": "child4",
"items": []
},
{
"label": "child5",
"items": ["item1","item2"]
}
]
}
]
And here is my incomplete solution:
function flattenDeep(arr) {
return arr.reduce(
(acc, val) =>
Array.isArray(val)
? acc.concat(flattenDeep(val.children))
: acc.concat(val.children),
[]
);
}
Upvotes: 0
Views: 123
Reputation: 122936
Here's a way to empty all items
arrays.
The idea is to use a predefined reducer method that can you can use recursively.
const reducer = (reduced, element) => {
// empty items array
if (element.items) {
element.items.length = 0;
}
// if element has children, recursively empty items array from it
if (element.children) {
element.children = element.children.reduce(reducer, []);
}
return reduced.concat(element); // or: [...reduced, element]
};
document.querySelector("pre").textContent =
JSON.stringify(getObj().reduce(reducer, []), null, " ");
// to keep relevant code on top of the snippet
function getObj() {
return [
{
"label": "parent",
"children": [
{
"label": "child1",
"children": [
{
"label": "child2",
"items": [
"item1",
"item2"
]
},
{
"label": "child3",
"items": [
"item1",
"item2",
"item3"
]
}
]
},
{
"label": "child4",
"items": []
},
{
"label": "child5",
"items": ["item1","item2"]
}
]
}
];
}
<pre></pre>
Upvotes: 1