Reputation: 1207
I have this JSON payload, where each object contains an ID, name and array of children. Here I need to get the IDs of all the elements, including the root and all the nested children.
{
"_id": "-1",
"_name": "root",
"_children": [
{
"_id": "1",
"_name": "Child 1",
"_children": [
{
"_id": "1-1",
"_name": "Child 1-1",
"_children": [
{
"_id": "1-1-1",
"_name": "Child 1-1-1",
"_children": [
]
}
]
},
{
"_id": "1-2",
"_name": "Child 1-2",
"_children": [
]
},
{
"_id": "1-3",
"_name": "Child 1-3",
"_children": [
]
}
]
},
{
"_id": "2",
"_name": "Child 2",
"_children": [
{
"_id": "2-2",
"_name": "Child 2-2",
"_children": [
]
}
]
}
]
}
How can I loop through this to get the ID values of all children and the root?
This is what I had tried using a nested function, but it is not working.
getNestedChildren(arr) {
var out = []
for(var i in arr[0].children) {
out.push(arr[i].id);
if(arr[i].children && arr[i].children.size() > 0) {
var children = this.getNestedChildren(arr[i].children)
}
}
Upvotes: 2
Views: 2853
Reputation: 51037
Here's a solution which works essentially the same way as @samdouble's answer; push the current node's ID to a result array, then recurse on the node's children.
The result array has to be created before calling the recursive function, so for convenience, that can be wrapped in an outer function; this saves the caller having to create an empty array to pass to the function.
interface TreeNode {
_id: string;
_name: string;
_children: TreeNode[];
}
function getIds(data: TreeNode): string[] {
const result: string[] = [];
function helper(node: TreeNode): void {
result.push(node._id);
node._children.forEach(helper);
}
helper(data);
return result;
}
Upvotes: 1
Reputation: 474
You can use recursion and modify a "result array" by reference.
For example, if your nested object is stored in a variable data
, then:
function addNestedChildrenToArray(obj, resultArray) {
resultArray.push(obj._id);
obj._children.forEach(child => addNestedChildrenToArray(child, resultArray));
}
const resultArray = [];
addNestedChildrenToArray(data, resultArray);
// resultArray now contains the results
console.log(resultArray);
You can test it here: https://es6console.com/k6ehwu5p/
Upvotes: 4
Reputation: 1088
You can flatten a tree and then simply get ids. See working example here
const tree = {
"_id": "-1",
"_name": "root",
"_children": [
// ...
]
}
function flattenTree(tree) {
if (!tree) {
return [];
}
if (tree._children) {
const result = tree._children.reduce((prev, current) => prev.concat(flattenTree(current)), [tree]);
return result;
} else {
return [tree];
}
}
const plain = flattenTree(tree);
const ids = plain.map(value => value._id);
Upvotes: 1