0

I'm having trouble getting the output from the following json

`[
 {theLevel:1,displayName: "John Doe1", index:1, parIndex:null },
 {theLevel:1,displayName: "John Doe2", index:2, parIndex:null },
 {theLevel:2,displayName: "John Doe3", index:3, parIndex:1 },
 {theLevel:2,displayName: "John Doe4", index:4, parIndex:1 },
 {theLevel:3,displayName: "John Doe5", index:5, parIndex:2 },
 {theLevel:3,displayName: "John Doe6", index:6, parIndex:2 },
]`

My expected output is as follows:

  [
      {text:"John Doe1", items:[{text:"John Doe3"},{text:"John Doe4"} ]},
      {text: "John Doe2, items:[{text:"John Doe5"},{text:"John Doe6"}]} ]
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Siafu
  • 25
  • 4
  • And what JavaScript are you using in order to obtain your expected output? – David Thomas Feb 14 '15 at 01:20
  • I tried a so many things, can't get anything to work. – Siafu Feb 14 '15 at 01:28
  • My apologies, I was suggesting that you need to show us some of your attempts, and explain where they went wrong; what did they do that they shouldn't, what didn't they do that they should? As it is, we have some input, your desired output and nothing else, which feels like you're just asking us to solve your problem without explaining what your problem is. – David Thomas Feb 14 '15 at 01:34
  • My attempts probably wont add any value, as I didn't even get close. I'll keep trying thanks for your time. – Siafu Feb 14 '15 at 01:50
  • I'm voting to close this question as off-topic because the user is asking to get his work done without showing any effort from his side – Ahmad Alfy Feb 19 '15 at 00:23
  • possible duplicate of [Access / process (nested) objects, arrays or JSON](http://stackoverflow.com/questions/11922383/access-process-nested-objects-arrays-or-json) – Qantas 94 Heavy Feb 19 '15 at 07:48

2 Answers2

1

Here's one solution which does a few iterations of the whole data to produce a tree. Some of these iterations can be combined to improve performance but here I've left them as they are so that it's clearer what's going on:

  1. Add a children property to each person

    _.each(data, function(person){
        _.extend(person, {children: []});
    });
    
  2. Create a hash of the data with the index of the person as the key and the person as the value

    var people = _.reduce(data, function(memo, person){
        memo[person.index] = person
        return memo;
    }, {} ); 
    

    The people object will look like so:

    {
       1: {theLevel:1,displayName: "John Doe1", index:1, parIndex:null },
       2: {theLevel:1,displayName: "John Doe2", index:2, parIndex:null },
       3: {theLevel:2,displayName: "John Doe3", index:3, parIndex:1 }
       etc.
    }
    
  3. Add each child to the children of it's parent:

    _.each(data, function(person){
        if( !_.isNull(person.parIndex)) people[person.parIndex].children.push(person);
    });
    

    This will leave you with a tree.

  4. You can then transform this tree into whatever you like. This snippet will produce the output in the question:

    function isParent (person) {
        return !_.isEmpty(person.children);
    }
    
    var parents = _.filter(people, isParent);
    
    var result = _.map(parents, function(person){
        return {
            text: person.displayName,
            items: _.map(person.children, function(child){
                return { text: child.displayName };
            })
        };
    
Gruff Bunny
  • 27,738
  • 10
  • 72
  • 59
  • Worked fine, I think that I only need the items array if there actually are children but I should be able to handle that. Thanks. – Siafu Feb 15 '15 at 05:52
  • Have added a filter to extract just the parents. – Gruff Bunny Feb 15 '15 at 10:53
  • I'll have to give that a shot, this will work with any number of levels ? Because the first level is the top level then I keeps going. I could have the items array nested several times. – Siafu Feb 15 '15 at 15:58
  • Yes, step 3 builds a tree by iterating over all the data and adding each person to their parent's children collection. – Gruff Bunny Feb 15 '15 at 16:53
  • the last transformation seems to be flatting the nesting to only two levels. var result = _.map(parents, function(person){ return { text: person.displayName, items: _.map(person.children, function(child){ return { text: child.displayName }; }) }; – Siafu Feb 17 '15 at 15:08
0

I did the following which seems to work with one minor issue. I'm getting an empty items array for some of the children. I would rather there be nothing if the items's array is empty.

  1. Add children and text property

    = _.each(results.data, function (entity) {
              _.extend(entity, { text: entity.displayName });
              _.extend(entity, { items: [] });
       });
    
  2. Create hash as before

      = _.reduce(results.data, function (memo, entities) {
                        memo[entities.entIndex] = entities;
                        return memo;
                    }, {});
    
  3. Add each child to parent as before

    = _.each(results.data, function (entity) {
        if (!_.isNull(entity.parEntIndex)) ent[entity.parEntIndex].items.push(entity);
                    });
    

    4.

    function isParent (entity) {
                        return !_.isEmpty(entity.items) && entity.theLev == 1;
                    }
    
                    var test = _.filter(combine, isParent);
    
                    var result = _.map(test, function (currentObject) {
                        return _.pick(currentObject,'text','items');
                    });
    
Siafu
  • 25
  • 4