0

I am looking to turn this flat array into an nested array but it keeps returning as empty. Not sure how to solve this one or what I am missing but this is driving me crazy.

Flat array:

var names =[
{ name: 'b', parent: 'Brown' },
{ name: 'a', parent: 'Brown' },
{ name: 'h', parent: 'Green' },
{ name: 'c', parent: 'Green' },
];

Desired output of array:

[{
    name: 'Brown',
    children: [{
            name: 'a',
            children: []
        },
        {
            name: 'b',
            children: []
        }
    ]
}, {
    name: 'Green',
        children: [{
                name: 'h',
                children: []
            },
            {
                name: 'c',
                children: []
            }
        ]
    }
}]

Js:

function getNestedChildren(arr, parent) {
    var children = [];
    for(var i =0; i < arr.length; ++i) {
        if(arr[i].parent == parent) {
            var grandChildren = getNestedChildren(arr, arr[i].name)

            if(grandChildren.length) {
                arr[i].children = grandChildren;
            }
            children.push( arr[i]);
        }
    }
    return children;
}
var nest = getNestedChildren(names, names.parent);
console.log( nest);
7
  • var nest = getNestedChildren(names, names.parent); what is names.parent? undefined? Commented May 2, 2018 at 15:38
  • you have to loop through the names and call parent for each one names[0].parent (otherwise its undefined) Commented May 2, 2018 at 15:40
  • I am trying to get to the root level of the array. Any thoughts? Commented May 2, 2018 at 15:40
  • @user992731 use 0 to get the root level. See my answer below Commented May 2, 2018 at 15:41
  • Also, this might be interesting for you: how-to-group-an-array-of-objects-by-key (copied wrong link first, edited) Commented May 2, 2018 at 15:43

3 Answers 3

1

var names =[
{ name: 'b', parent: 'Brown' },
{ name: 'a', parent: 'Brown' },
{ name: 'h', parent: 'Green' },
{ name: 'c', parent: 'Green' },
{ name: 'j', parent: 'Brown' }
];

function groupBy(arr, f) {
  return arr.reduce((r, v, i, a, k = f(v)) => ((r[k] || (r[k] = [])).push(v), r), {});
}

function nestArray(array){
  var newArray=[],
      resultGrouped = groupBy(names, function(c) {
    return c.parent
  });
  
  for (var key in resultGrouped){
    var item=resultGrouped[key];
    
    newArray.push({
      name:key,
      children:item.map(function(map){
        delete map.parent;
        map.children=[];
        return map;
      })
    });
  }
  
  return newArray;
}
console.log(nestArray(names));

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

Comments

1

You can create a new object, for each item assign an array to a key with the parent name, and concatenate the item to that array

var names =[
{ name: 'b', parent: 'Brown' },
{ name: 'a', parent: 'Brown' },
{ name: 'h', parent: 'Green' },
{ name: 'c', parent: 'Green' },
];

const getGroup=(groups, parent) => {
  let group = groups.find(g=>g.parent===parent);
  if(!group){
    group=({parent,children:[]});
    groups.push(group);
  }
  return group;
}

let  grouped = []
 names.forEach(item=> getGroup(grouped,item.parent).children.push(item))
 
                             
console.log(grouped)

1 Comment

Your results don't look like the OP's desired result.
0

So for starters, you need to loop through the names and send each parent to your getNestedChildren() function.

var names =[
    { name: 'b', parent: 'Brown' },
    { name: 'a', parent: 'Brown' },
    { name: 'h', parent: 'Green' },
    { name: 'c', parent: 'Green' },
];

var nest = [];

for (var i = 0; i < names.length; i++) {
    nest.push(getNestedChildren(names, names[i].parent));
} 

Also your getNestedChildren() is currently trying to modify and send back the old names array. I'd suggest creating a new object instead and send back the object with the children on it.

function getNestedChildren(arr, parent) {
    var children = [];
    var parentObj = {};
    parentObj.name = parent;
    for(var i =0; i < arr.length; ++i) {
        if(arr[i].parent == parent) {
            children.push(getNestedChildren(arr, arr[i].name));
        }
    }
    parentObj.children = children;
    return parentObj;
}

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.