Skip to content
Advertisement

Create a nested array recursively in Node.js

Following is my array

[
    {id: 1, title: 'hello', parent: {number:0}},
    {id: 2, title: 'hello', parent: {number:0}},
    {id: 3, title: 'hello', parent: {number:1}},
    {id: 4, title: 'hello', parent: {number:3}},
    {id: 5, title: 'hello', parent: {number:4}},
    {id: 6, title: 'hello', parent: {number:4}},
    {id: 7, title: 'hello', parent: {number:3}},
    {id: 8, title: 'hello', parent: {number:2}}
]

and I want to have objects nested like this as output :

[
    {id: 1, title: 'hello', parent: 0, children: [
        {id: 3, title: 'hello', parent: 1, children: [
            {id: 4, title: 'hello', parent: 3, children: [
                {id: 5, title: 'hello', parent: 4},
                {id: 6, title: 'hello', parent: 4}
            ]},
            {id: 7, title: 'hello', parent: 3}
        ]}
    ]},
    {id: 2, title: 'hello', parent: 0, children: [
        {id: 8, title: 'hello', parent: 2}
    ]}
]

Please help me with a recursive function to do this in node.js.

Following is the recursive function is what I have tried:

    function getNestedChildren(arr, parent) {
    var out = []
    for(var i in arr) {
        if(arr[i].parent.number == parent.number) {
            var children = getNestedChildren(arr, arr[i].id)

            if(children.length) {
                arr[i].children = children
            }
            out.push(arr[i])
        }
    }
    return out
}

Please help me to solve this. I am a newbie in this.

Advertisement

Answer

Renaming some variables helped me solve this.

  • getNestedChildren returns an array of children, so rename out to children.
  • the children returned by the recursive call are the grandchildren of the parent being processed in the call. So call the result of the recursive call grandchildren.

The problem that caused the code to not work:

  • line 4 of the posted code uses the id property of the parent parameter. So either ensure that every call to getNestedChidren provides an object with such a property (as below), or change the second argument to parentNumber and just supply the numeric value of the number property. Your choice.

Lastly, avoid using for ... in loops to iterate an array – please do a web search for more information and discussion.

var array = [
    {id: 1, title: 'hello', parent: {number:0}},
    {id: 2, title: 'hello', parent: {number:0}},
    {id: 3, title: 'hello', parent: {number:1}},
    {id: 4, title: 'hello', parent: {number:3}},
    {id: 5, title: 'hello', parent: {number:4}},
    {id: 6, title: 'hello', parent: {number:4}},
    {id: 7, title: 'hello', parent: {number:3}},
    {id: 8, title: 'hello', parent: {number:2}}
]
function getNestedChildren(arr, parent) {
    var children = [];
    for(var i =0; i < arr.length; ++i) {
        if(arr[i].parent.number == parent.number) {
            var grandChildren = getNestedChildren(arr, {number: arr[i].id})

            if(grandChildren.length) {
                arr[i].children = grandChildren;
            }
            children.push( arr[i]);
        }
    }
    return children;
}
var nest = getNestedChildren(array,{number: 0});
console.log( nest);
Advertisement