I have a nested array of objects:
const nestArray = [
{
title: "title 1",
children: [
{
title: "title 1-1",
children: [
{ title: "title 1-1-1", children: [...] },
{ title: "title 1-1-2", children: [...] }
]
},
{
title: "title 1-2",
children: [
{ title: "title 1-2-1", children: [...] },
{ title: "title 1-2-2", children: [...] }
]
},
]
},
{...},
{...}
]
All objects have the same interface:
interface Obj {
title: string
children: Obj[]
}
I need to put a new key into each object called keys
.
The keys
will keep all its children's titles alongside its own title. So the final result should be:
const nestArray = [
{
title: "title 1",
keys: ["title 1", "title 1-1", "title 1-1-1", "title 1-1-2"],
children: [
{
title: "title 1-1",
keys: ["title 1-1", "title 1-1-1", "title 1-1-2"],
children: [
{ title: "title 1-1-1", keys: ["title 1-1-1"], children: [] },
{ title: "title 1-1-2", keys: ["title 1-1-2"], children: [] }
]
},
{
title: "title 1-2",
keys: ["title 1-2", "title 1-2-1", "title 1-2-2"],
children: [
{ title: "title 1-2-1", keys: ["title 1-2-1"], children: [] },
{ title: "title 1-2-2", keys: ["title 1-2-2"], children: [] }
]
},
]
},
{...},
{...}
]
so the interface will be changed as:
interface Obj {
title: string
children: Obj[]
keys: string[]
}
I searched a lot but couldn't find any solution on the internet. I tried to solve this problem on my own, using recursive functions but still, I couldn't do it.
Using lodash is fine
What i've tried so far:
const mapTitlesToKeys = (obj) => {
obj.keys = [obj.title];
obj.children.forEach((childObj) => {
mapTitlesToKeys(childObj);
obj.keys.push(childObj.title);
});
};
nestArray.forEach((obj) => {
mapTitlesToKeys(obj);
});
console.log(nestArray);
results in:
[
{
title: "title 1",
keys: ['title 1', 'title 1-1', 'title 1-2'], // <-- should be ["title 1", "title 1-1", "title 1-1-1", "title 1-1-2"]
children: [
{
title: "title 1-1",
keys: ['title 1-1', 'title 1-1-1', 'title 1-1-2'], // <-- should be ["title 1-1", "title 1-1-1", "title 1-1-2"]
children: [
{
title: "title 1-1-1",
keys: ["title 1-1-1"], // <-- fine
children: []
},
{
title: "title 1-1-2",
keys: ["title 1-1-2"], // <-- fine
children: []
}
]
},
{
title: "title 1-2",
keys: ['title 1-2', 'title 1-2-1', 'title 1-2-2'], // <-- should be ["title 1-2", "title 1-2-1", "title 1-2-2"]
children: [
{
title: "title 1-2-1",
keys: ["title 1-2-1"], // <-- fine
children: []
},
{
title: "title 1-2-2",
keys: ["title 1-2-2"], // <-- fine
children: []
}
]
},
]
},
{...},
{...}
]
CodePudding user response:
Presented below is one possible way to achieve the desired objective.
Code Snippet
const addKeysTo = arr => (
arr.map(
({ title, children }) => {
const cArr = addKeysTo(children);
keys = [title, ...cArr.flatMap(({ keys }) => keys )];
return ({ title, keys, children: cArr });
}
)
);
/* explanation of the method
// method to add "keys" array to each elt
const addKeysTo = arr => (
// use ".map()" to iterate over given array
arr.map(
// destructure to access "title", "children"
({ title, children }) => {
// recurse to obtain updated childre-narray
const cArr = addKeysTo(children);
// construct "keys" array for current elt
keys = [title, ...cArr.flatMap(({ keys }) => keys )];
// explicit return of current elt of "arr" array with "keys" prop
return ({ title, keys, children: cArr });
}
) // implicit return from the method
);
*/
const nestArray = [{
title: "title 1",
children: [{
title: "title 1-1",
children: [{
title: "title 1-1-1",
children: []
},
{
title: "title 1-1-2",
children: []
}
]
},
{
title: "title 1-2",
children: [{
title: "title 1-2-1",
children: []
},
{
title: "title 1-2-2",
children: []
}
]
},
]
}];
console.log(
'added keys to nested-objects array...\n',
addKeysTo(nestArray)
);
.as-console-wrapper { max-height: 100% !important; top: 0 }
Explanation
Inline comments added to the snippet above.
CodePudding user response:
Something like this? (Shorter version... No need to keep the old one)
const nestArray = [{
title: "title 1",
children: [{
title: "title 1-1",
children: [{
title: "title 1-1-1",
children: []
},
{
title: "title 1-1-2",
children: []
}
]
},
{
title: "title 1-2",
children: [{
title: "title 1-2-1",
children: []
},
{
title: "title 1-2-2",
children: []
}
]
},
]
}]
function add_keys_obj(obj) {
obj.keys = [obj.title];
obj.children.forEach(function(child) {
add_keys_obj(child)
obj.keys.push(...child.keys)
})
}
function add_keys(arr) {
arr.forEach(function(obj, key) {
add_keys_obj(obj);
})
return arr;
}
add_keys(nestArray)
document.querySelector("pre").innerText = JSON.stringify(nestArray, null, 2);
<pre></pre>