Reputation: 6745
I have the following piece of json
, it follows a specific pattern but each object can have any number of children
and each of those children
objects can have any number of children
..
[
{
"name": "1st level",
"parentId": "",
"id": "dummyvalue1",
"children": [
{
"name": "2nd level child",
"parentId": "dummyvalue1",
"id": "dummyvalue2"
},
{
"name": "another 2nd level child",
"id": "dummyvalue3",
"children": [
{
"name": "3rd level child",
"id": "dummyvalue4",
"children": [
{
"name": "4th level child",
"parentId": "dummyvalue4",
"id": "dummyvalue5"
}
],
"parentId": "dummyvalue3"
}
],
"parentId": "dummyvalue1"
}
]
}
]
The problem is, I only need to access objects at a specific depth within this nested object
/array
structure.
And that depth
is dynamic.
If the depth
equals 3, then I would like to add a new dummy object into the children
array for that level. So the new structure would look like this ..
[
{
"name": "1st level",
"parentId": "",
"id": "dummyvalue1",
"children": [
{
"name": "2nd level child",
"parentId": "dummyvalue1",
"id": "dummyvalue2"
},
{
"name": "another 2nd level child",
"id": "dummyvalue3",
"children": [
{
"name": "3rd level child",
"id": "dummyvalue4",
"children": [
{
"name": "4th level child",
"parentId": "dummyvalue4",
"id": "dummyvalue5"
}
],
"parentId": "dummyvalue3"
},
{
"name": "NEW OBJECT",
"parentId": "dummyvalue3",
"id": "random"
}
],
"parentId": "dummyvalue1"
}
]
}
]
Is there a clean way to do this? Instead of huge loops trying to iterate to the right level. Also dont think I can use dot notation since the number of levels and the depth
variable is dynamic
Upvotes: 0
Views: 201
Reputation: 7605
I've created this function:
function addChild(currentChild, childToAdd, depth) {
if (depth === 1) {
currentChild.children.push(childToAdd);
return;
}
const nextChild = currentChild.children.filter(child => child.children && child.children.length)[0];
if (!nextChild) {
if (currentChild.children && currentChild.children.length) {
currentChild.children[0].children = [childToAdd];
} else {
currentChild.children = [childToAdd];
}
return;
}
addChild(nextChild, childToAdd, depth - 1);
}
It takes 3 arguments:
If the depth
is 1, it simply add the child
to the children
. If not, it looks inside the children
, take the first one with children
and make a recursive call to the same function.
const data = [
{
"name": "1st level",
"parentId": "",
"id": "dummyvalue1",
"children": [
{
"name": "2nd level child",
"parentId": "dummyvalue1",
"id": "dummyvalue2"
},
{
"name": "another 2nd level child",
"id": "dummyvalue3",
"children": [
{
"name": "3rd level child",
"id": "dummyvalue4",
"children": [
{
"name": "4th level child",
"parentId": "dummyvalue4",
"id": "dummyvalue5"
}
],
"parentId": "dummyvalue3"
}
],
"parentId": "dummyvalue1"
}
]
}
]
function addChild(currentChild, childToAdd, depth) {
if (depth === 1) {
currentChild.children.push(childToAdd);
return;
}
const nextChild = currentChild.children.filter(child => child.children && child.children.length)[0];
if (!nextChild) {
if (currentChild.children && currentChild.children.length) {
currentChild.children[0].children = [childToAdd];
} else {
currentChild.children = [childToAdd];
}
return;
}
addChild(nextChild, childToAdd, depth - 1);
}
addChild(data[0], {foo: 'bar'}, 3);
addChild(data[0], {bar: 'baz'}, 2);
addChild(data[0], {baz: 'foo'}, 1);
addChild(data[0], {extraChild: 'foo'}, 4);
console.log(data);
Upvotes: 1