Create nested array data from an array of objects












4















I have an array of objects that has information of nested data, and I want to convert the data to actual nested array data.
How can I convert this:



const data = [
{id: 1, parent_id: null, name: 'test1'},
{id: 2, parent_id: null, name: 'test2'},
{id: 3, parent_id: 2, name: 'test3'},
{id: 4, parent_id: 2, name: 'test4'},
{id: 5, parent_id: 4, name: 'test5'},
{id: 6, parent_id: 4, name: 'test5'},
{id: 7, parent_id: 2, name: 'test5'},
{id: 8, parent_id: 2, name: 'test5'},
{id: 9, parent_id: null, name: 'test5'},
{id: 10, parent_id: null, name: 'test5'},
]


to this:



const data = [
{id: 1, parent_id: null, name: 'test1'},
{
id: 2,
parent_id: null,
name: 'test2',
children: [
{id: 3, parent_id: 2, name: 'test3'},
{
id: 4,
parent_id: 2,
name: 'test4',
children: [
{id: 5, parent_id: 4, name: 'test5'},
{id: 6, parent_id: 4, name: 'test5'}
]
},
{id: 7, parent_id: 2, name: 'test5'},
{id: 8, parent_id: 2, name: 'test5'},
]
},
{id: 9, parent_id: null, name: 'test5'},
{id: 10, parent_id: null, name: 'test5'},
]


What is the best way to do this?










share|improve this question





























    4















    I have an array of objects that has information of nested data, and I want to convert the data to actual nested array data.
    How can I convert this:



    const data = [
    {id: 1, parent_id: null, name: 'test1'},
    {id: 2, parent_id: null, name: 'test2'},
    {id: 3, parent_id: 2, name: 'test3'},
    {id: 4, parent_id: 2, name: 'test4'},
    {id: 5, parent_id: 4, name: 'test5'},
    {id: 6, parent_id: 4, name: 'test5'},
    {id: 7, parent_id: 2, name: 'test5'},
    {id: 8, parent_id: 2, name: 'test5'},
    {id: 9, parent_id: null, name: 'test5'},
    {id: 10, parent_id: null, name: 'test5'},
    ]


    to this:



    const data = [
    {id: 1, parent_id: null, name: 'test1'},
    {
    id: 2,
    parent_id: null,
    name: 'test2',
    children: [
    {id: 3, parent_id: 2, name: 'test3'},
    {
    id: 4,
    parent_id: 2,
    name: 'test4',
    children: [
    {id: 5, parent_id: 4, name: 'test5'},
    {id: 6, parent_id: 4, name: 'test5'}
    ]
    },
    {id: 7, parent_id: 2, name: 'test5'},
    {id: 8, parent_id: 2, name: 'test5'},
    ]
    },
    {id: 9, parent_id: null, name: 'test5'},
    {id: 10, parent_id: null, name: 'test5'},
    ]


    What is the best way to do this?










    share|improve this question



























      4












      4








      4








      I have an array of objects that has information of nested data, and I want to convert the data to actual nested array data.
      How can I convert this:



      const data = [
      {id: 1, parent_id: null, name: 'test1'},
      {id: 2, parent_id: null, name: 'test2'},
      {id: 3, parent_id: 2, name: 'test3'},
      {id: 4, parent_id: 2, name: 'test4'},
      {id: 5, parent_id: 4, name: 'test5'},
      {id: 6, parent_id: 4, name: 'test5'},
      {id: 7, parent_id: 2, name: 'test5'},
      {id: 8, parent_id: 2, name: 'test5'},
      {id: 9, parent_id: null, name: 'test5'},
      {id: 10, parent_id: null, name: 'test5'},
      ]


      to this:



      const data = [
      {id: 1, parent_id: null, name: 'test1'},
      {
      id: 2,
      parent_id: null,
      name: 'test2',
      children: [
      {id: 3, parent_id: 2, name: 'test3'},
      {
      id: 4,
      parent_id: 2,
      name: 'test4',
      children: [
      {id: 5, parent_id: 4, name: 'test5'},
      {id: 6, parent_id: 4, name: 'test5'}
      ]
      },
      {id: 7, parent_id: 2, name: 'test5'},
      {id: 8, parent_id: 2, name: 'test5'},
      ]
      },
      {id: 9, parent_id: null, name: 'test5'},
      {id: 10, parent_id: null, name: 'test5'},
      ]


      What is the best way to do this?










      share|improve this question
















      I have an array of objects that has information of nested data, and I want to convert the data to actual nested array data.
      How can I convert this:



      const data = [
      {id: 1, parent_id: null, name: 'test1'},
      {id: 2, parent_id: null, name: 'test2'},
      {id: 3, parent_id: 2, name: 'test3'},
      {id: 4, parent_id: 2, name: 'test4'},
      {id: 5, parent_id: 4, name: 'test5'},
      {id: 6, parent_id: 4, name: 'test5'},
      {id: 7, parent_id: 2, name: 'test5'},
      {id: 8, parent_id: 2, name: 'test5'},
      {id: 9, parent_id: null, name: 'test5'},
      {id: 10, parent_id: null, name: 'test5'},
      ]


      to this:



      const data = [
      {id: 1, parent_id: null, name: 'test1'},
      {
      id: 2,
      parent_id: null,
      name: 'test2',
      children: [
      {id: 3, parent_id: 2, name: 'test3'},
      {
      id: 4,
      parent_id: 2,
      name: 'test4',
      children: [
      {id: 5, parent_id: 4, name: 'test5'},
      {id: 6, parent_id: 4, name: 'test5'}
      ]
      },
      {id: 7, parent_id: 2, name: 'test5'},
      {id: 8, parent_id: 2, name: 'test5'},
      ]
      },
      {id: 9, parent_id: null, name: 'test5'},
      {id: 10, parent_id: null, name: 'test5'},
      ]


      What is the best way to do this?







      javascript arrays json






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 20 '18 at 22:19







      Dan

















      asked Nov 20 '18 at 15:21









      DanDan

      5741514




      5741514
























          5 Answers
          5






          active

          oldest

          votes


















          3














          You could create recursive function with reduce method for this.






          const data = [{id: 1, parent_id: null, name: 'test1'},{id: 2, parent_id: null, name: 'test2'},{id: 3, parent_id: 2, name: 'test3'},{id: 4, parent_id: 2, name: 'test4'},{id: 5, parent_id: 4, name: 'test5'},{id: 6, parent_id: 4, name: 'test5'},{id: 7, parent_id: 2, name: 'test5'},{id: 8, parent_id: 2, name: 'test5'},{id: 9, parent_id: null, name: 'test5'},{id: 10, parent_id: null, name: 'test5'},]

          function nest(data, parentId = null) {
          return data.reduce((r, e) => {
          let obj = Object.assign({}, e)
          if (parentId == e.parent_id) {
          let children = nest(data, e.id)
          if (children.length) obj.children = children
          r.push(obj)
          }
          return r;
          }, )
          }

          console.log(nest(data))








          share|improve this answer































            2














            You could take a single loop approach by using an object and the id and parent_id as key and collect the items/children to it.



            The order is only important for the order in the children array.






            const
            data = [{ id: 1, parent_id: null, name: 'test1' }, { id: 2, parent_id: null, name: 'test2' }, { id: 3, parent_id: 2, name: 'test3' }, { id: 4, parent_id: 2, name: 'test4' }, { id: 5, parent_id: 4, name: 'test5' }, { id: 6, parent_id: 4, name: 'test5' }, { id: 7, parent_id: 2, name: 'test5' }, { id: 8, parent_id: 2, name: 'test5' }, { id: 9, parent_id: null, name: 'test5' }, { id: 10, parent_id: null, name: 'test5' }],
            tree = function (data, root) {
            var o = {};
            data.forEach(function (a) {
            Object.assign(o[a.id] = o[a.id] || {}, a, o[a.id] && o[a.id].children && { children: o[a.id].children });
            o[a.parent_id] = o[a.parent_id] || {};
            o[a.parent_id].children = o[a.parent_id].children || ;
            o[a.parent_id].children.push(o[a.id]);
            });
            return o[root].children;
            }(data, null);

            console.log(tree);

            .as-console-wrapper { max-height: 100% !important; top: 0; }








            share|improve this answer


























            • Does this depend on the order? For example if id:1 has a parent of 4, it seems like it ends up in the wrong place.

              – Mark Meyer
              Nov 20 '18 at 15:48











            • @MarkMeyer, the order does not matter for parent children relations.

              – Nina Scholz
              Nov 20 '18 at 15:52













            • Hmm, not sure what it is. If I change the parent of item id:1 from null to 4 it ends up in the wrong place.

              – Mark Meyer
              Nov 20 '18 at 16:01













            • please look below, children array comes first, but the item is in the right place.

              – Nina Scholz
              Nov 20 '18 at 16:04











            • I apologize — you are right! Just couldn't read my own output :(.

              – Mark Meyer
              Nov 20 '18 at 16:06



















            0














            This is an interesting problem. One option if you want to keep linear time at the expense of some space it to make a lookup object based on id. Then you can loop through those values and push into either a parent object or the array:






            const data = [{id: 1, parent_id: null, name: 'test1'},{id: 2, parent_id: null, name: 'test2'},{id: 3, parent_id: 2, name: 'test3'},{id: 4, parent_id: 2, name: 'test4'},{id: 5, parent_id: 4, name: 'test5'},{id: 6, parent_id: 4, name: 'test5'},{id: 7, parent_id: 2, name: 'test5'},{id: 8, parent_id: 2, name: 'test5'},{id: 9, parent_id: null, name: 'test5'},{id: 10, parent_id: null, name: 'test5'},]

            let lookup = data.reduce((obj, item) => {
            obj[item.id] = item
            return obj
            }, {})

            let arr = Object.values(lookup).reduce((arr, val) =>{
            if (val.parent_id == null) arr.push(val)
            else (lookup[val.parent_id].children || ( lookup[val.parent_id].children = )).push(val)

            return arr
            }, )

            console.log(JSON.stringify(arr, null, 2))








            share|improve this answer































              0














              you could try this recursive approach






              const data = [{id: 1, parent_id: null, name: 'test1'}, {id: 2, parent_id: null, name: 'test2'}, {id: 3, parent_id: 2, name: 'test3'}, {id: 4, parent_id: 2, name: 'test4'}, {id: 5, parent_id: 4, name: 'test5'}, {id: 6, parent_id: 4, name: 'test5'}, {id: 7, parent_id: 2, name: 'test5'}, {id: 8, parent_id: 2, name: 'test5'}, {id: 9, parent_id: null, name: 'test5'}, {id: 10, parent_id: null, name: 'test5'}];

              const transform = arr => {
              return arr.reduce((acc, elem) => {
              const children = data.filter(el => el.parent_id === elem.id),
              isPresent = findDeep(acc, elem);
              if(!isPresent && children.length)
              acc.push({...elem, children: transform(children)});
              else if(!isPresent)
              acc.push(elem);
              return acc;
              }, );
              }


              const findDeep =(arr = , elem) => (
              arr.some(el => (el.id === elem.id) || findDeep(el.children, elem))
              );

              console.log(transform(data));








              share|improve this answer

































                -1

















                const data = [
                {id: 1, parent_id: null, name: 'test1'},
                {id: 2, parent_id: null, name: 'test2'},
                {id: 3, parent_id: 2, name: 'test3'},
                {id: 4, parent_id: 2, name: 'test4'},
                {id: 5, parent_id: 4, name: 'test5'},
                {id: 6, parent_id: 4, name: 'test5'},
                {id: 7, parent_id: 2, name: 'test5'},
                {id: 8, parent_id: 2, name: 'test5'},
                {id: 9, parent_id: null, name: 'test5'},
                {id: 10, parent_id: null, name: 'test5'},
                ]

                const output = data.filter(
                item => !item.parent_id
                ).map(
                rootItem => ({
                ...rootItem,
                children: data.filter(item => item.parent_id === rootItem.id),
                })
                )

                console.log(output)








                share|improve this answer



















                • 1





                  What happened it id: 5?

                  – Mark Meyer
                  Nov 20 '18 at 15:37











                • Ah you're right there is more than one level of nesting, the best answer is probably the one using reduce.

                  – alexjackson
                  Nov 20 '18 at 15:39











                Your Answer






                StackExchange.ifUsing("editor", function () {
                StackExchange.using("externalEditor", function () {
                StackExchange.using("snippets", function () {
                StackExchange.snippets.init();
                });
                });
                }, "code-snippets");

                StackExchange.ready(function() {
                var channelOptions = {
                tags: "".split(" "),
                id: "1"
                };
                initTagRenderer("".split(" "), "".split(" "), channelOptions);

                StackExchange.using("externalEditor", function() {
                // Have to fire editor after snippets, if snippets enabled
                if (StackExchange.settings.snippets.snippetsEnabled) {
                StackExchange.using("snippets", function() {
                createEditor();
                });
                }
                else {
                createEditor();
                }
                });

                function createEditor() {
                StackExchange.prepareEditor({
                heartbeatType: 'answer',
                autoActivateHeartbeat: false,
                convertImagesToLinks: true,
                noModals: true,
                showLowRepImageUploadWarning: true,
                reputationToPostImages: 10,
                bindNavPrevention: true,
                postfix: "",
                imageUploader: {
                brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                allowUrls: true
                },
                onDemand: true,
                discardSelector: ".discard-answer"
                ,immediatelyShowMarkdownHelp:true
                });


                }
                });














                draft saved

                draft discarded


















                StackExchange.ready(
                function () {
                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53396194%2fcreate-nested-array-data-from-an-array-of-objects%23new-answer', 'question_page');
                }
                );

                Post as a guest















                Required, but never shown

























                5 Answers
                5






                active

                oldest

                votes








                5 Answers
                5






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes









                3














                You could create recursive function with reduce method for this.






                const data = [{id: 1, parent_id: null, name: 'test1'},{id: 2, parent_id: null, name: 'test2'},{id: 3, parent_id: 2, name: 'test3'},{id: 4, parent_id: 2, name: 'test4'},{id: 5, parent_id: 4, name: 'test5'},{id: 6, parent_id: 4, name: 'test5'},{id: 7, parent_id: 2, name: 'test5'},{id: 8, parent_id: 2, name: 'test5'},{id: 9, parent_id: null, name: 'test5'},{id: 10, parent_id: null, name: 'test5'},]

                function nest(data, parentId = null) {
                return data.reduce((r, e) => {
                let obj = Object.assign({}, e)
                if (parentId == e.parent_id) {
                let children = nest(data, e.id)
                if (children.length) obj.children = children
                r.push(obj)
                }
                return r;
                }, )
                }

                console.log(nest(data))








                share|improve this answer




























                  3














                  You could create recursive function with reduce method for this.






                  const data = [{id: 1, parent_id: null, name: 'test1'},{id: 2, parent_id: null, name: 'test2'},{id: 3, parent_id: 2, name: 'test3'},{id: 4, parent_id: 2, name: 'test4'},{id: 5, parent_id: 4, name: 'test5'},{id: 6, parent_id: 4, name: 'test5'},{id: 7, parent_id: 2, name: 'test5'},{id: 8, parent_id: 2, name: 'test5'},{id: 9, parent_id: null, name: 'test5'},{id: 10, parent_id: null, name: 'test5'},]

                  function nest(data, parentId = null) {
                  return data.reduce((r, e) => {
                  let obj = Object.assign({}, e)
                  if (parentId == e.parent_id) {
                  let children = nest(data, e.id)
                  if (children.length) obj.children = children
                  r.push(obj)
                  }
                  return r;
                  }, )
                  }

                  console.log(nest(data))








                  share|improve this answer


























                    3












                    3








                    3







                    You could create recursive function with reduce method for this.






                    const data = [{id: 1, parent_id: null, name: 'test1'},{id: 2, parent_id: null, name: 'test2'},{id: 3, parent_id: 2, name: 'test3'},{id: 4, parent_id: 2, name: 'test4'},{id: 5, parent_id: 4, name: 'test5'},{id: 6, parent_id: 4, name: 'test5'},{id: 7, parent_id: 2, name: 'test5'},{id: 8, parent_id: 2, name: 'test5'},{id: 9, parent_id: null, name: 'test5'},{id: 10, parent_id: null, name: 'test5'},]

                    function nest(data, parentId = null) {
                    return data.reduce((r, e) => {
                    let obj = Object.assign({}, e)
                    if (parentId == e.parent_id) {
                    let children = nest(data, e.id)
                    if (children.length) obj.children = children
                    r.push(obj)
                    }
                    return r;
                    }, )
                    }

                    console.log(nest(data))








                    share|improve this answer













                    You could create recursive function with reduce method for this.






                    const data = [{id: 1, parent_id: null, name: 'test1'},{id: 2, parent_id: null, name: 'test2'},{id: 3, parent_id: 2, name: 'test3'},{id: 4, parent_id: 2, name: 'test4'},{id: 5, parent_id: 4, name: 'test5'},{id: 6, parent_id: 4, name: 'test5'},{id: 7, parent_id: 2, name: 'test5'},{id: 8, parent_id: 2, name: 'test5'},{id: 9, parent_id: null, name: 'test5'},{id: 10, parent_id: null, name: 'test5'},]

                    function nest(data, parentId = null) {
                    return data.reduce((r, e) => {
                    let obj = Object.assign({}, e)
                    if (parentId == e.parent_id) {
                    let children = nest(data, e.id)
                    if (children.length) obj.children = children
                    r.push(obj)
                    }
                    return r;
                    }, )
                    }

                    console.log(nest(data))








                    const data = [{id: 1, parent_id: null, name: 'test1'},{id: 2, parent_id: null, name: 'test2'},{id: 3, parent_id: 2, name: 'test3'},{id: 4, parent_id: 2, name: 'test4'},{id: 5, parent_id: 4, name: 'test5'},{id: 6, parent_id: 4, name: 'test5'},{id: 7, parent_id: 2, name: 'test5'},{id: 8, parent_id: 2, name: 'test5'},{id: 9, parent_id: null, name: 'test5'},{id: 10, parent_id: null, name: 'test5'},]

                    function nest(data, parentId = null) {
                    return data.reduce((r, e) => {
                    let obj = Object.assign({}, e)
                    if (parentId == e.parent_id) {
                    let children = nest(data, e.id)
                    if (children.length) obj.children = children
                    r.push(obj)
                    }
                    return r;
                    }, )
                    }

                    console.log(nest(data))





                    const data = [{id: 1, parent_id: null, name: 'test1'},{id: 2, parent_id: null, name: 'test2'},{id: 3, parent_id: 2, name: 'test3'},{id: 4, parent_id: 2, name: 'test4'},{id: 5, parent_id: 4, name: 'test5'},{id: 6, parent_id: 4, name: 'test5'},{id: 7, parent_id: 2, name: 'test5'},{id: 8, parent_id: 2, name: 'test5'},{id: 9, parent_id: null, name: 'test5'},{id: 10, parent_id: null, name: 'test5'},]

                    function nest(data, parentId = null) {
                    return data.reduce((r, e) => {
                    let obj = Object.assign({}, e)
                    if (parentId == e.parent_id) {
                    let children = nest(data, e.id)
                    if (children.length) obj.children = children
                    r.push(obj)
                    }
                    return r;
                    }, )
                    }

                    console.log(nest(data))






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Nov 20 '18 at 15:34









                    Nenad VracarNenad Vracar

                    71k115679




                    71k115679

























                        2














                        You could take a single loop approach by using an object and the id and parent_id as key and collect the items/children to it.



                        The order is only important for the order in the children array.






                        const
                        data = [{ id: 1, parent_id: null, name: 'test1' }, { id: 2, parent_id: null, name: 'test2' }, { id: 3, parent_id: 2, name: 'test3' }, { id: 4, parent_id: 2, name: 'test4' }, { id: 5, parent_id: 4, name: 'test5' }, { id: 6, parent_id: 4, name: 'test5' }, { id: 7, parent_id: 2, name: 'test5' }, { id: 8, parent_id: 2, name: 'test5' }, { id: 9, parent_id: null, name: 'test5' }, { id: 10, parent_id: null, name: 'test5' }],
                        tree = function (data, root) {
                        var o = {};
                        data.forEach(function (a) {
                        Object.assign(o[a.id] = o[a.id] || {}, a, o[a.id] && o[a.id].children && { children: o[a.id].children });
                        o[a.parent_id] = o[a.parent_id] || {};
                        o[a.parent_id].children = o[a.parent_id].children || ;
                        o[a.parent_id].children.push(o[a.id]);
                        });
                        return o[root].children;
                        }(data, null);

                        console.log(tree);

                        .as-console-wrapper { max-height: 100% !important; top: 0; }








                        share|improve this answer


























                        • Does this depend on the order? For example if id:1 has a parent of 4, it seems like it ends up in the wrong place.

                          – Mark Meyer
                          Nov 20 '18 at 15:48











                        • @MarkMeyer, the order does not matter for parent children relations.

                          – Nina Scholz
                          Nov 20 '18 at 15:52













                        • Hmm, not sure what it is. If I change the parent of item id:1 from null to 4 it ends up in the wrong place.

                          – Mark Meyer
                          Nov 20 '18 at 16:01













                        • please look below, children array comes first, but the item is in the right place.

                          – Nina Scholz
                          Nov 20 '18 at 16:04











                        • I apologize — you are right! Just couldn't read my own output :(.

                          – Mark Meyer
                          Nov 20 '18 at 16:06
















                        2














                        You could take a single loop approach by using an object and the id and parent_id as key and collect the items/children to it.



                        The order is only important for the order in the children array.






                        const
                        data = [{ id: 1, parent_id: null, name: 'test1' }, { id: 2, parent_id: null, name: 'test2' }, { id: 3, parent_id: 2, name: 'test3' }, { id: 4, parent_id: 2, name: 'test4' }, { id: 5, parent_id: 4, name: 'test5' }, { id: 6, parent_id: 4, name: 'test5' }, { id: 7, parent_id: 2, name: 'test5' }, { id: 8, parent_id: 2, name: 'test5' }, { id: 9, parent_id: null, name: 'test5' }, { id: 10, parent_id: null, name: 'test5' }],
                        tree = function (data, root) {
                        var o = {};
                        data.forEach(function (a) {
                        Object.assign(o[a.id] = o[a.id] || {}, a, o[a.id] && o[a.id].children && { children: o[a.id].children });
                        o[a.parent_id] = o[a.parent_id] || {};
                        o[a.parent_id].children = o[a.parent_id].children || ;
                        o[a.parent_id].children.push(o[a.id]);
                        });
                        return o[root].children;
                        }(data, null);

                        console.log(tree);

                        .as-console-wrapper { max-height: 100% !important; top: 0; }








                        share|improve this answer


























                        • Does this depend on the order? For example if id:1 has a parent of 4, it seems like it ends up in the wrong place.

                          – Mark Meyer
                          Nov 20 '18 at 15:48











                        • @MarkMeyer, the order does not matter for parent children relations.

                          – Nina Scholz
                          Nov 20 '18 at 15:52













                        • Hmm, not sure what it is. If I change the parent of item id:1 from null to 4 it ends up in the wrong place.

                          – Mark Meyer
                          Nov 20 '18 at 16:01













                        • please look below, children array comes first, but the item is in the right place.

                          – Nina Scholz
                          Nov 20 '18 at 16:04











                        • I apologize — you are right! Just couldn't read my own output :(.

                          – Mark Meyer
                          Nov 20 '18 at 16:06














                        2












                        2








                        2







                        You could take a single loop approach by using an object and the id and parent_id as key and collect the items/children to it.



                        The order is only important for the order in the children array.






                        const
                        data = [{ id: 1, parent_id: null, name: 'test1' }, { id: 2, parent_id: null, name: 'test2' }, { id: 3, parent_id: 2, name: 'test3' }, { id: 4, parent_id: 2, name: 'test4' }, { id: 5, parent_id: 4, name: 'test5' }, { id: 6, parent_id: 4, name: 'test5' }, { id: 7, parent_id: 2, name: 'test5' }, { id: 8, parent_id: 2, name: 'test5' }, { id: 9, parent_id: null, name: 'test5' }, { id: 10, parent_id: null, name: 'test5' }],
                        tree = function (data, root) {
                        var o = {};
                        data.forEach(function (a) {
                        Object.assign(o[a.id] = o[a.id] || {}, a, o[a.id] && o[a.id].children && { children: o[a.id].children });
                        o[a.parent_id] = o[a.parent_id] || {};
                        o[a.parent_id].children = o[a.parent_id].children || ;
                        o[a.parent_id].children.push(o[a.id]);
                        });
                        return o[root].children;
                        }(data, null);

                        console.log(tree);

                        .as-console-wrapper { max-height: 100% !important; top: 0; }








                        share|improve this answer















                        You could take a single loop approach by using an object and the id and parent_id as key and collect the items/children to it.



                        The order is only important for the order in the children array.






                        const
                        data = [{ id: 1, parent_id: null, name: 'test1' }, { id: 2, parent_id: null, name: 'test2' }, { id: 3, parent_id: 2, name: 'test3' }, { id: 4, parent_id: 2, name: 'test4' }, { id: 5, parent_id: 4, name: 'test5' }, { id: 6, parent_id: 4, name: 'test5' }, { id: 7, parent_id: 2, name: 'test5' }, { id: 8, parent_id: 2, name: 'test5' }, { id: 9, parent_id: null, name: 'test5' }, { id: 10, parent_id: null, name: 'test5' }],
                        tree = function (data, root) {
                        var o = {};
                        data.forEach(function (a) {
                        Object.assign(o[a.id] = o[a.id] || {}, a, o[a.id] && o[a.id].children && { children: o[a.id].children });
                        o[a.parent_id] = o[a.parent_id] || {};
                        o[a.parent_id].children = o[a.parent_id].children || ;
                        o[a.parent_id].children.push(o[a.id]);
                        });
                        return o[root].children;
                        }(data, null);

                        console.log(tree);

                        .as-console-wrapper { max-height: 100% !important; top: 0; }








                        const
                        data = [{ id: 1, parent_id: null, name: 'test1' }, { id: 2, parent_id: null, name: 'test2' }, { id: 3, parent_id: 2, name: 'test3' }, { id: 4, parent_id: 2, name: 'test4' }, { id: 5, parent_id: 4, name: 'test5' }, { id: 6, parent_id: 4, name: 'test5' }, { id: 7, parent_id: 2, name: 'test5' }, { id: 8, parent_id: 2, name: 'test5' }, { id: 9, parent_id: null, name: 'test5' }, { id: 10, parent_id: null, name: 'test5' }],
                        tree = function (data, root) {
                        var o = {};
                        data.forEach(function (a) {
                        Object.assign(o[a.id] = o[a.id] || {}, a, o[a.id] && o[a.id].children && { children: o[a.id].children });
                        o[a.parent_id] = o[a.parent_id] || {};
                        o[a.parent_id].children = o[a.parent_id].children || ;
                        o[a.parent_id].children.push(o[a.id]);
                        });
                        return o[root].children;
                        }(data, null);

                        console.log(tree);

                        .as-console-wrapper { max-height: 100% !important; top: 0; }





                        const
                        data = [{ id: 1, parent_id: null, name: 'test1' }, { id: 2, parent_id: null, name: 'test2' }, { id: 3, parent_id: 2, name: 'test3' }, { id: 4, parent_id: 2, name: 'test4' }, { id: 5, parent_id: 4, name: 'test5' }, { id: 6, parent_id: 4, name: 'test5' }, { id: 7, parent_id: 2, name: 'test5' }, { id: 8, parent_id: 2, name: 'test5' }, { id: 9, parent_id: null, name: 'test5' }, { id: 10, parent_id: null, name: 'test5' }],
                        tree = function (data, root) {
                        var o = {};
                        data.forEach(function (a) {
                        Object.assign(o[a.id] = o[a.id] || {}, a, o[a.id] && o[a.id].children && { children: o[a.id].children });
                        o[a.parent_id] = o[a.parent_id] || {};
                        o[a.parent_id].children = o[a.parent_id].children || ;
                        o[a.parent_id].children.push(o[a.id]);
                        });
                        return o[root].children;
                        }(data, null);

                        console.log(tree);

                        .as-console-wrapper { max-height: 100% !important; top: 0; }






                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited Nov 20 '18 at 15:51

























                        answered Nov 20 '18 at 15:39









                        Nina ScholzNina Scholz

                        181k1494163




                        181k1494163













                        • Does this depend on the order? For example if id:1 has a parent of 4, it seems like it ends up in the wrong place.

                          – Mark Meyer
                          Nov 20 '18 at 15:48











                        • @MarkMeyer, the order does not matter for parent children relations.

                          – Nina Scholz
                          Nov 20 '18 at 15:52













                        • Hmm, not sure what it is. If I change the parent of item id:1 from null to 4 it ends up in the wrong place.

                          – Mark Meyer
                          Nov 20 '18 at 16:01













                        • please look below, children array comes first, but the item is in the right place.

                          – Nina Scholz
                          Nov 20 '18 at 16:04











                        • I apologize — you are right! Just couldn't read my own output :(.

                          – Mark Meyer
                          Nov 20 '18 at 16:06



















                        • Does this depend on the order? For example if id:1 has a parent of 4, it seems like it ends up in the wrong place.

                          – Mark Meyer
                          Nov 20 '18 at 15:48











                        • @MarkMeyer, the order does not matter for parent children relations.

                          – Nina Scholz
                          Nov 20 '18 at 15:52













                        • Hmm, not sure what it is. If I change the parent of item id:1 from null to 4 it ends up in the wrong place.

                          – Mark Meyer
                          Nov 20 '18 at 16:01













                        • please look below, children array comes first, but the item is in the right place.

                          – Nina Scholz
                          Nov 20 '18 at 16:04











                        • I apologize — you are right! Just couldn't read my own output :(.

                          – Mark Meyer
                          Nov 20 '18 at 16:06

















                        Does this depend on the order? For example if id:1 has a parent of 4, it seems like it ends up in the wrong place.

                        – Mark Meyer
                        Nov 20 '18 at 15:48





                        Does this depend on the order? For example if id:1 has a parent of 4, it seems like it ends up in the wrong place.

                        – Mark Meyer
                        Nov 20 '18 at 15:48













                        @MarkMeyer, the order does not matter for parent children relations.

                        – Nina Scholz
                        Nov 20 '18 at 15:52







                        @MarkMeyer, the order does not matter for parent children relations.

                        – Nina Scholz
                        Nov 20 '18 at 15:52















                        Hmm, not sure what it is. If I change the parent of item id:1 from null to 4 it ends up in the wrong place.

                        – Mark Meyer
                        Nov 20 '18 at 16:01







                        Hmm, not sure what it is. If I change the parent of item id:1 from null to 4 it ends up in the wrong place.

                        – Mark Meyer
                        Nov 20 '18 at 16:01















                        please look below, children array comes first, but the item is in the right place.

                        – Nina Scholz
                        Nov 20 '18 at 16:04





                        please look below, children array comes first, but the item is in the right place.

                        – Nina Scholz
                        Nov 20 '18 at 16:04













                        I apologize — you are right! Just couldn't read my own output :(.

                        – Mark Meyer
                        Nov 20 '18 at 16:06





                        I apologize — you are right! Just couldn't read my own output :(.

                        – Mark Meyer
                        Nov 20 '18 at 16:06











                        0














                        This is an interesting problem. One option if you want to keep linear time at the expense of some space it to make a lookup object based on id. Then you can loop through those values and push into either a parent object or the array:






                        const data = [{id: 1, parent_id: null, name: 'test1'},{id: 2, parent_id: null, name: 'test2'},{id: 3, parent_id: 2, name: 'test3'},{id: 4, parent_id: 2, name: 'test4'},{id: 5, parent_id: 4, name: 'test5'},{id: 6, parent_id: 4, name: 'test5'},{id: 7, parent_id: 2, name: 'test5'},{id: 8, parent_id: 2, name: 'test5'},{id: 9, parent_id: null, name: 'test5'},{id: 10, parent_id: null, name: 'test5'},]

                        let lookup = data.reduce((obj, item) => {
                        obj[item.id] = item
                        return obj
                        }, {})

                        let arr = Object.values(lookup).reduce((arr, val) =>{
                        if (val.parent_id == null) arr.push(val)
                        else (lookup[val.parent_id].children || ( lookup[val.parent_id].children = )).push(val)

                        return arr
                        }, )

                        console.log(JSON.stringify(arr, null, 2))








                        share|improve this answer




























                          0














                          This is an interesting problem. One option if you want to keep linear time at the expense of some space it to make a lookup object based on id. Then you can loop through those values and push into either a parent object or the array:






                          const data = [{id: 1, parent_id: null, name: 'test1'},{id: 2, parent_id: null, name: 'test2'},{id: 3, parent_id: 2, name: 'test3'},{id: 4, parent_id: 2, name: 'test4'},{id: 5, parent_id: 4, name: 'test5'},{id: 6, parent_id: 4, name: 'test5'},{id: 7, parent_id: 2, name: 'test5'},{id: 8, parent_id: 2, name: 'test5'},{id: 9, parent_id: null, name: 'test5'},{id: 10, parent_id: null, name: 'test5'},]

                          let lookup = data.reduce((obj, item) => {
                          obj[item.id] = item
                          return obj
                          }, {})

                          let arr = Object.values(lookup).reduce((arr, val) =>{
                          if (val.parent_id == null) arr.push(val)
                          else (lookup[val.parent_id].children || ( lookup[val.parent_id].children = )).push(val)

                          return arr
                          }, )

                          console.log(JSON.stringify(arr, null, 2))








                          share|improve this answer


























                            0












                            0








                            0







                            This is an interesting problem. One option if you want to keep linear time at the expense of some space it to make a lookup object based on id. Then you can loop through those values and push into either a parent object or the array:






                            const data = [{id: 1, parent_id: null, name: 'test1'},{id: 2, parent_id: null, name: 'test2'},{id: 3, parent_id: 2, name: 'test3'},{id: 4, parent_id: 2, name: 'test4'},{id: 5, parent_id: 4, name: 'test5'},{id: 6, parent_id: 4, name: 'test5'},{id: 7, parent_id: 2, name: 'test5'},{id: 8, parent_id: 2, name: 'test5'},{id: 9, parent_id: null, name: 'test5'},{id: 10, parent_id: null, name: 'test5'},]

                            let lookup = data.reduce((obj, item) => {
                            obj[item.id] = item
                            return obj
                            }, {})

                            let arr = Object.values(lookup).reduce((arr, val) =>{
                            if (val.parent_id == null) arr.push(val)
                            else (lookup[val.parent_id].children || ( lookup[val.parent_id].children = )).push(val)

                            return arr
                            }, )

                            console.log(JSON.stringify(arr, null, 2))








                            share|improve this answer













                            This is an interesting problem. One option if you want to keep linear time at the expense of some space it to make a lookup object based on id. Then you can loop through those values and push into either a parent object or the array:






                            const data = [{id: 1, parent_id: null, name: 'test1'},{id: 2, parent_id: null, name: 'test2'},{id: 3, parent_id: 2, name: 'test3'},{id: 4, parent_id: 2, name: 'test4'},{id: 5, parent_id: 4, name: 'test5'},{id: 6, parent_id: 4, name: 'test5'},{id: 7, parent_id: 2, name: 'test5'},{id: 8, parent_id: 2, name: 'test5'},{id: 9, parent_id: null, name: 'test5'},{id: 10, parent_id: null, name: 'test5'},]

                            let lookup = data.reduce((obj, item) => {
                            obj[item.id] = item
                            return obj
                            }, {})

                            let arr = Object.values(lookup).reduce((arr, val) =>{
                            if (val.parent_id == null) arr.push(val)
                            else (lookup[val.parent_id].children || ( lookup[val.parent_id].children = )).push(val)

                            return arr
                            }, )

                            console.log(JSON.stringify(arr, null, 2))








                            const data = [{id: 1, parent_id: null, name: 'test1'},{id: 2, parent_id: null, name: 'test2'},{id: 3, parent_id: 2, name: 'test3'},{id: 4, parent_id: 2, name: 'test4'},{id: 5, parent_id: 4, name: 'test5'},{id: 6, parent_id: 4, name: 'test5'},{id: 7, parent_id: 2, name: 'test5'},{id: 8, parent_id: 2, name: 'test5'},{id: 9, parent_id: null, name: 'test5'},{id: 10, parent_id: null, name: 'test5'},]

                            let lookup = data.reduce((obj, item) => {
                            obj[item.id] = item
                            return obj
                            }, {})

                            let arr = Object.values(lookup).reduce((arr, val) =>{
                            if (val.parent_id == null) arr.push(val)
                            else (lookup[val.parent_id].children || ( lookup[val.parent_id].children = )).push(val)

                            return arr
                            }, )

                            console.log(JSON.stringify(arr, null, 2))





                            const data = [{id: 1, parent_id: null, name: 'test1'},{id: 2, parent_id: null, name: 'test2'},{id: 3, parent_id: 2, name: 'test3'},{id: 4, parent_id: 2, name: 'test4'},{id: 5, parent_id: 4, name: 'test5'},{id: 6, parent_id: 4, name: 'test5'},{id: 7, parent_id: 2, name: 'test5'},{id: 8, parent_id: 2, name: 'test5'},{id: 9, parent_id: null, name: 'test5'},{id: 10, parent_id: null, name: 'test5'},]

                            let lookup = data.reduce((obj, item) => {
                            obj[item.id] = item
                            return obj
                            }, {})

                            let arr = Object.values(lookup).reduce((arr, val) =>{
                            if (val.parent_id == null) arr.push(val)
                            else (lookup[val.parent_id].children || ( lookup[val.parent_id].children = )).push(val)

                            return arr
                            }, )

                            console.log(JSON.stringify(arr, null, 2))






                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Nov 20 '18 at 15:56









                            Mark MeyerMark Meyer

                            38.1k33159




                            38.1k33159























                                0














                                you could try this recursive approach






                                const data = [{id: 1, parent_id: null, name: 'test1'}, {id: 2, parent_id: null, name: 'test2'}, {id: 3, parent_id: 2, name: 'test3'}, {id: 4, parent_id: 2, name: 'test4'}, {id: 5, parent_id: 4, name: 'test5'}, {id: 6, parent_id: 4, name: 'test5'}, {id: 7, parent_id: 2, name: 'test5'}, {id: 8, parent_id: 2, name: 'test5'}, {id: 9, parent_id: null, name: 'test5'}, {id: 10, parent_id: null, name: 'test5'}];

                                const transform = arr => {
                                return arr.reduce((acc, elem) => {
                                const children = data.filter(el => el.parent_id === elem.id),
                                isPresent = findDeep(acc, elem);
                                if(!isPresent && children.length)
                                acc.push({...elem, children: transform(children)});
                                else if(!isPresent)
                                acc.push(elem);
                                return acc;
                                }, );
                                }


                                const findDeep =(arr = , elem) => (
                                arr.some(el => (el.id === elem.id) || findDeep(el.children, elem))
                                );

                                console.log(transform(data));








                                share|improve this answer






























                                  0














                                  you could try this recursive approach






                                  const data = [{id: 1, parent_id: null, name: 'test1'}, {id: 2, parent_id: null, name: 'test2'}, {id: 3, parent_id: 2, name: 'test3'}, {id: 4, parent_id: 2, name: 'test4'}, {id: 5, parent_id: 4, name: 'test5'}, {id: 6, parent_id: 4, name: 'test5'}, {id: 7, parent_id: 2, name: 'test5'}, {id: 8, parent_id: 2, name: 'test5'}, {id: 9, parent_id: null, name: 'test5'}, {id: 10, parent_id: null, name: 'test5'}];

                                  const transform = arr => {
                                  return arr.reduce((acc, elem) => {
                                  const children = data.filter(el => el.parent_id === elem.id),
                                  isPresent = findDeep(acc, elem);
                                  if(!isPresent && children.length)
                                  acc.push({...elem, children: transform(children)});
                                  else if(!isPresent)
                                  acc.push(elem);
                                  return acc;
                                  }, );
                                  }


                                  const findDeep =(arr = , elem) => (
                                  arr.some(el => (el.id === elem.id) || findDeep(el.children, elem))
                                  );

                                  console.log(transform(data));








                                  share|improve this answer




























                                    0












                                    0








                                    0







                                    you could try this recursive approach






                                    const data = [{id: 1, parent_id: null, name: 'test1'}, {id: 2, parent_id: null, name: 'test2'}, {id: 3, parent_id: 2, name: 'test3'}, {id: 4, parent_id: 2, name: 'test4'}, {id: 5, parent_id: 4, name: 'test5'}, {id: 6, parent_id: 4, name: 'test5'}, {id: 7, parent_id: 2, name: 'test5'}, {id: 8, parent_id: 2, name: 'test5'}, {id: 9, parent_id: null, name: 'test5'}, {id: 10, parent_id: null, name: 'test5'}];

                                    const transform = arr => {
                                    return arr.reduce((acc, elem) => {
                                    const children = data.filter(el => el.parent_id === elem.id),
                                    isPresent = findDeep(acc, elem);
                                    if(!isPresent && children.length)
                                    acc.push({...elem, children: transform(children)});
                                    else if(!isPresent)
                                    acc.push(elem);
                                    return acc;
                                    }, );
                                    }


                                    const findDeep =(arr = , elem) => (
                                    arr.some(el => (el.id === elem.id) || findDeep(el.children, elem))
                                    );

                                    console.log(transform(data));








                                    share|improve this answer















                                    you could try this recursive approach






                                    const data = [{id: 1, parent_id: null, name: 'test1'}, {id: 2, parent_id: null, name: 'test2'}, {id: 3, parent_id: 2, name: 'test3'}, {id: 4, parent_id: 2, name: 'test4'}, {id: 5, parent_id: 4, name: 'test5'}, {id: 6, parent_id: 4, name: 'test5'}, {id: 7, parent_id: 2, name: 'test5'}, {id: 8, parent_id: 2, name: 'test5'}, {id: 9, parent_id: null, name: 'test5'}, {id: 10, parent_id: null, name: 'test5'}];

                                    const transform = arr => {
                                    return arr.reduce((acc, elem) => {
                                    const children = data.filter(el => el.parent_id === elem.id),
                                    isPresent = findDeep(acc, elem);
                                    if(!isPresent && children.length)
                                    acc.push({...elem, children: transform(children)});
                                    else if(!isPresent)
                                    acc.push(elem);
                                    return acc;
                                    }, );
                                    }


                                    const findDeep =(arr = , elem) => (
                                    arr.some(el => (el.id === elem.id) || findDeep(el.children, elem))
                                    );

                                    console.log(transform(data));








                                    const data = [{id: 1, parent_id: null, name: 'test1'}, {id: 2, parent_id: null, name: 'test2'}, {id: 3, parent_id: 2, name: 'test3'}, {id: 4, parent_id: 2, name: 'test4'}, {id: 5, parent_id: 4, name: 'test5'}, {id: 6, parent_id: 4, name: 'test5'}, {id: 7, parent_id: 2, name: 'test5'}, {id: 8, parent_id: 2, name: 'test5'}, {id: 9, parent_id: null, name: 'test5'}, {id: 10, parent_id: null, name: 'test5'}];

                                    const transform = arr => {
                                    return arr.reduce((acc, elem) => {
                                    const children = data.filter(el => el.parent_id === elem.id),
                                    isPresent = findDeep(acc, elem);
                                    if(!isPresent && children.length)
                                    acc.push({...elem, children: transform(children)});
                                    else if(!isPresent)
                                    acc.push(elem);
                                    return acc;
                                    }, );
                                    }


                                    const findDeep =(arr = , elem) => (
                                    arr.some(el => (el.id === elem.id) || findDeep(el.children, elem))
                                    );

                                    console.log(transform(data));





                                    const data = [{id: 1, parent_id: null, name: 'test1'}, {id: 2, parent_id: null, name: 'test2'}, {id: 3, parent_id: 2, name: 'test3'}, {id: 4, parent_id: 2, name: 'test4'}, {id: 5, parent_id: 4, name: 'test5'}, {id: 6, parent_id: 4, name: 'test5'}, {id: 7, parent_id: 2, name: 'test5'}, {id: 8, parent_id: 2, name: 'test5'}, {id: 9, parent_id: null, name: 'test5'}, {id: 10, parent_id: null, name: 'test5'}];

                                    const transform = arr => {
                                    return arr.reduce((acc, elem) => {
                                    const children = data.filter(el => el.parent_id === elem.id),
                                    isPresent = findDeep(acc, elem);
                                    if(!isPresent && children.length)
                                    acc.push({...elem, children: transform(children)});
                                    else if(!isPresent)
                                    acc.push(elem);
                                    return acc;
                                    }, );
                                    }


                                    const findDeep =(arr = , elem) => (
                                    arr.some(el => (el.id === elem.id) || findDeep(el.children, elem))
                                    );

                                    console.log(transform(data));






                                    share|improve this answer














                                    share|improve this answer



                                    share|improve this answer








                                    edited Nov 20 '18 at 17:07

























                                    answered Nov 20 '18 at 16:05









                                    KarimKarim

                                    5,0691720




                                    5,0691720























                                        -1

















                                        const data = [
                                        {id: 1, parent_id: null, name: 'test1'},
                                        {id: 2, parent_id: null, name: 'test2'},
                                        {id: 3, parent_id: 2, name: 'test3'},
                                        {id: 4, parent_id: 2, name: 'test4'},
                                        {id: 5, parent_id: 4, name: 'test5'},
                                        {id: 6, parent_id: 4, name: 'test5'},
                                        {id: 7, parent_id: 2, name: 'test5'},
                                        {id: 8, parent_id: 2, name: 'test5'},
                                        {id: 9, parent_id: null, name: 'test5'},
                                        {id: 10, parent_id: null, name: 'test5'},
                                        ]

                                        const output = data.filter(
                                        item => !item.parent_id
                                        ).map(
                                        rootItem => ({
                                        ...rootItem,
                                        children: data.filter(item => item.parent_id === rootItem.id),
                                        })
                                        )

                                        console.log(output)








                                        share|improve this answer



















                                        • 1





                                          What happened it id: 5?

                                          – Mark Meyer
                                          Nov 20 '18 at 15:37











                                        • Ah you're right there is more than one level of nesting, the best answer is probably the one using reduce.

                                          – alexjackson
                                          Nov 20 '18 at 15:39
















                                        -1

















                                        const data = [
                                        {id: 1, parent_id: null, name: 'test1'},
                                        {id: 2, parent_id: null, name: 'test2'},
                                        {id: 3, parent_id: 2, name: 'test3'},
                                        {id: 4, parent_id: 2, name: 'test4'},
                                        {id: 5, parent_id: 4, name: 'test5'},
                                        {id: 6, parent_id: 4, name: 'test5'},
                                        {id: 7, parent_id: 2, name: 'test5'},
                                        {id: 8, parent_id: 2, name: 'test5'},
                                        {id: 9, parent_id: null, name: 'test5'},
                                        {id: 10, parent_id: null, name: 'test5'},
                                        ]

                                        const output = data.filter(
                                        item => !item.parent_id
                                        ).map(
                                        rootItem => ({
                                        ...rootItem,
                                        children: data.filter(item => item.parent_id === rootItem.id),
                                        })
                                        )

                                        console.log(output)








                                        share|improve this answer



















                                        • 1





                                          What happened it id: 5?

                                          – Mark Meyer
                                          Nov 20 '18 at 15:37











                                        • Ah you're right there is more than one level of nesting, the best answer is probably the one using reduce.

                                          – alexjackson
                                          Nov 20 '18 at 15:39














                                        -1












                                        -1








                                        -1










                                        const data = [
                                        {id: 1, parent_id: null, name: 'test1'},
                                        {id: 2, parent_id: null, name: 'test2'},
                                        {id: 3, parent_id: 2, name: 'test3'},
                                        {id: 4, parent_id: 2, name: 'test4'},
                                        {id: 5, parent_id: 4, name: 'test5'},
                                        {id: 6, parent_id: 4, name: 'test5'},
                                        {id: 7, parent_id: 2, name: 'test5'},
                                        {id: 8, parent_id: 2, name: 'test5'},
                                        {id: 9, parent_id: null, name: 'test5'},
                                        {id: 10, parent_id: null, name: 'test5'},
                                        ]

                                        const output = data.filter(
                                        item => !item.parent_id
                                        ).map(
                                        rootItem => ({
                                        ...rootItem,
                                        children: data.filter(item => item.parent_id === rootItem.id),
                                        })
                                        )

                                        console.log(output)








                                        share|improve this answer
















                                        const data = [
                                        {id: 1, parent_id: null, name: 'test1'},
                                        {id: 2, parent_id: null, name: 'test2'},
                                        {id: 3, parent_id: 2, name: 'test3'},
                                        {id: 4, parent_id: 2, name: 'test4'},
                                        {id: 5, parent_id: 4, name: 'test5'},
                                        {id: 6, parent_id: 4, name: 'test5'},
                                        {id: 7, parent_id: 2, name: 'test5'},
                                        {id: 8, parent_id: 2, name: 'test5'},
                                        {id: 9, parent_id: null, name: 'test5'},
                                        {id: 10, parent_id: null, name: 'test5'},
                                        ]

                                        const output = data.filter(
                                        item => !item.parent_id
                                        ).map(
                                        rootItem => ({
                                        ...rootItem,
                                        children: data.filter(item => item.parent_id === rootItem.id),
                                        })
                                        )

                                        console.log(output)








                                        const data = [
                                        {id: 1, parent_id: null, name: 'test1'},
                                        {id: 2, parent_id: null, name: 'test2'},
                                        {id: 3, parent_id: 2, name: 'test3'},
                                        {id: 4, parent_id: 2, name: 'test4'},
                                        {id: 5, parent_id: 4, name: 'test5'},
                                        {id: 6, parent_id: 4, name: 'test5'},
                                        {id: 7, parent_id: 2, name: 'test5'},
                                        {id: 8, parent_id: 2, name: 'test5'},
                                        {id: 9, parent_id: null, name: 'test5'},
                                        {id: 10, parent_id: null, name: 'test5'},
                                        ]

                                        const output = data.filter(
                                        item => !item.parent_id
                                        ).map(
                                        rootItem => ({
                                        ...rootItem,
                                        children: data.filter(item => item.parent_id === rootItem.id),
                                        })
                                        )

                                        console.log(output)





                                        const data = [
                                        {id: 1, parent_id: null, name: 'test1'},
                                        {id: 2, parent_id: null, name: 'test2'},
                                        {id: 3, parent_id: 2, name: 'test3'},
                                        {id: 4, parent_id: 2, name: 'test4'},
                                        {id: 5, parent_id: 4, name: 'test5'},
                                        {id: 6, parent_id: 4, name: 'test5'},
                                        {id: 7, parent_id: 2, name: 'test5'},
                                        {id: 8, parent_id: 2, name: 'test5'},
                                        {id: 9, parent_id: null, name: 'test5'},
                                        {id: 10, parent_id: null, name: 'test5'},
                                        ]

                                        const output = data.filter(
                                        item => !item.parent_id
                                        ).map(
                                        rootItem => ({
                                        ...rootItem,
                                        children: data.filter(item => item.parent_id === rootItem.id),
                                        })
                                        )

                                        console.log(output)






                                        share|improve this answer












                                        share|improve this answer



                                        share|improve this answer










                                        answered Nov 20 '18 at 15:35









                                        alexjacksonalexjackson

                                        221




                                        221








                                        • 1





                                          What happened it id: 5?

                                          – Mark Meyer
                                          Nov 20 '18 at 15:37











                                        • Ah you're right there is more than one level of nesting, the best answer is probably the one using reduce.

                                          – alexjackson
                                          Nov 20 '18 at 15:39














                                        • 1





                                          What happened it id: 5?

                                          – Mark Meyer
                                          Nov 20 '18 at 15:37











                                        • Ah you're right there is more than one level of nesting, the best answer is probably the one using reduce.

                                          – alexjackson
                                          Nov 20 '18 at 15:39








                                        1




                                        1





                                        What happened it id: 5?

                                        – Mark Meyer
                                        Nov 20 '18 at 15:37





                                        What happened it id: 5?

                                        – Mark Meyer
                                        Nov 20 '18 at 15:37













                                        Ah you're right there is more than one level of nesting, the best answer is probably the one using reduce.

                                        – alexjackson
                                        Nov 20 '18 at 15:39





                                        Ah you're right there is more than one level of nesting, the best answer is probably the one using reduce.

                                        – alexjackson
                                        Nov 20 '18 at 15:39


















                                        draft saved

                                        draft discarded




















































                                        Thanks for contributing an answer to Stack Overflow!


                                        • Please be sure to answer the question. Provide details and share your research!

                                        But avoid



                                        • Asking for help, clarification, or responding to other answers.

                                        • Making statements based on opinion; back them up with references or personal experience.


                                        To learn more, see our tips on writing great answers.




                                        draft saved


                                        draft discarded














                                        StackExchange.ready(
                                        function () {
                                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53396194%2fcreate-nested-array-data-from-an-array-of-objects%23new-answer', 'question_page');
                                        }
                                        );

                                        Post as a guest















                                        Required, but never shown





















































                                        Required, but never shown














                                        Required, but never shown












                                        Required, but never shown







                                        Required, but never shown

































                                        Required, but never shown














                                        Required, but never shown












                                        Required, but never shown







                                        Required, but never shown







                                        Popular posts from this blog

                                        MongoDB - Not Authorized To Execute Command

                                        How to fix TextFormField cause rebuild widget in Flutter

                                        Npm cannot find a required file even through it is in the searched directory