3

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'}]
        },
      ]
    },
  ]
}
4
  • 1
    your data structure is not valid. arrays have no property in a literal. Commented Mar 3, 2017 at 11:13
  • if you make it correct then use recursion tech to cater this. 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. Commented Mar 3, 2017 at 11:18
  • btw, what qualifies a deep node? or would you like to get all nodes? Commented Mar 3, 2017 at 11:19

2 Answers 2

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; }

Sign up to request clarification or add additional context in comments.

Comments

2

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));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.