admin管理员组

文章数量:1317909

I have 2 types of a objects, a group, and an item. A group can have children which is either an array of groups or an array of items.

I've ended up with a series of nested groups (which can be infinite levels deep) and I need to retrieve all the items, no matter how many levels deep, with only a group to work with.

Is there a way to retrieve all the items from the top-level group in the following data structure?

{
  type: 'group',
  children: [
    {
      type: 'group',
      children: [
        {
          type: 'group',
          children: [{type:'item'}, {type:'item'}, {type:'item'}]
        },
        {
          type: 'group',
          children: [{type:'item'}, {type:'item'}, {type:'item'}]
        },
        {
          type: 'group',
          children: [{type:'item'}, {type:'item'}, {type:'item'}]
        },
      ]
    },
    {
      type: 'group',
      children: [
        {
          type: 'group',
          children: [{type:'item'}]
        },
        {
          type: 'group',
          children: [{type:'item'}]
        },
        {
          type: 'group',
          children: [{type:'item'}]
        },
      ]
    },
    {
      type: 'group',
      children: [
        {
          type: 'group',
          children: [{type:'item'}, {type:'item'}]
        },
        {
          type: 'group',
          children: [{type:'item'}, {type:'item'}]
        },
        {
          type: 'group',
          children: [{type:'item'}, {type:'item'}]
        },
      ]
    },
  ]
}

I have 2 types of a objects, a group, and an item. A group can have children which is either an array of groups or an array of items.

I've ended up with a series of nested groups (which can be infinite levels deep) and I need to retrieve all the items, no matter how many levels deep, with only a group to work with.

Is there a way to retrieve all the items from the top-level group in the following data structure?

{
  type: 'group',
  children: [
    {
      type: 'group',
      children: [
        {
          type: 'group',
          children: [{type:'item'}, {type:'item'}, {type:'item'}]
        },
        {
          type: 'group',
          children: [{type:'item'}, {type:'item'}, {type:'item'}]
        },
        {
          type: 'group',
          children: [{type:'item'}, {type:'item'}, {type:'item'}]
        },
      ]
    },
    {
      type: 'group',
      children: [
        {
          type: 'group',
          children: [{type:'item'}]
        },
        {
          type: 'group',
          children: [{type:'item'}]
        },
        {
          type: 'group',
          children: [{type:'item'}]
        },
      ]
    },
    {
      type: 'group',
      children: [
        {
          type: 'group',
          children: [{type:'item'}, {type:'item'}]
        },
        {
          type: 'group',
          children: [{type:'item'}, {type:'item'}]
        },
        {
          type: 'group',
          children: [{type:'item'}, {type:'item'}]
        },
      ]
    },
  ]
}
Share Improve this question edited Mar 3, 2017 at 11:34 Ryan King asked Mar 3, 2017 at 11:11 Ryan KingRyan King 3,69612 gold badges50 silver badges73 bronze badges 4
  • 1 your data structure is not valid. arrays have no property in a literal. – Nina Scholz Commented Mar 3, 2017 at 11:13
  • if you make it correct then use recursion tech to cater this. – Jai Commented Mar 3, 2017 at 11:15
  • As you won't have property labels available to you in an actual array, how will you differentiate between an array of group objects and array of item objects? If you can show an example of an actual array and include the group and item object definitions this might be easier. – Nope Commented Mar 3, 2017 at 11:18
  • btw, what qualifies a deep node? or would you like to get all nodes? – Nina Scholz Commented Mar 3, 2017 at 11:19
Add a ment  | 

2 Answers 2

Reset to default 7

You could use an iterative with Array#reduce and recursive with calling iter again, approach.

var data = { children: [{ children: [{ children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }] }, { children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }] }, { children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }] }] }, { children: [{ children: [{ name: 'item1' }] }, { children: [{ name: 'item1' }] }, { children: [{ name: 'item1' }] }] }, { children: [{ children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }] }, { children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }] }, { children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }] }] }] },
    children = [data].reduce(function iter(r, a) {
        if (Array.isArray(a.children)) {
            return a.children.reduce(iter, r);
        }
        r.push(a);
        return r;
    }, []);

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

You can achieve it with recursion.

var data = {
  children: [
    {
      children: [
        {
          children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }]
        },
        {
          children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }]
        },
        {
          children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }]
        }
      ]
    },
    {
      children: [
        {
          children: [{ name: 'item1' }]
        },
        {
          children: [{ name: 'item1' }]
        },
        {
          children: [{ name: 'item1' }]
        }
      ]
    },
    {
      children: [
        {
          children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }]
        },
        {
          children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }]
        },
        {
          children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }]
        }
      ]
    }
  ]
};


function getAllChildren(group, children) {
  children = children || [];
  if(group && Array.isArray(group.children)) {
    group.children.forEach(function(child) { 
      getAllChildren(child, children)
    });
  }
  else {
    children.push(group);
  }
  return children;
}

console.log(getAllChildren(data));

本文标签: Get deepest level children from nested objects in javascriptStack Overflow