1

I have following type of data

data = [{
    "grp" : ["A", "B", "C"],
    "val" : [1, 2, 3]
  }, {
    "grp" : ["A", "B", "D"],
    "val" : [2, 3, 4]
  }, {
    "grp" : ["A", "C", "C"],
    "val" : [1, 3, 5]
  }, {
    "grp" : ["B", "Y", "E"],
    "val" : [1, 3, 2]
  }
]

I want to make groups like these

groups = {
  "A": {
    "B": {
      "C": [
        [1, 2, 3],
        [2, 3, 4]
      ],
      "D": [
        [1, 2, 3],
        [2, 3, 4]
      ]
    },
    "C": {
      "C": [
        [1, 3, 5]
      ]
    }
  },
  "B": {
    "Y": {
      "E": [
        [1, 3, 2]
      ]
    }
  }
}

grp array can be have maximum of 3 elements.

I tried using underscorejs something like below, however, I ended up creating individual groups, not nested groups.

var groups = _(data).reduce(function(memo, o) {
    _(o.groups).each(function(j) {
        memo[j] = memo[j] || [ ];
        memo[j].push(o);
    });
    return memo;
}, { });

Would appreciate any idea in the right direction.

3
  • 1
    What happened to "grp" : ["B", "X"] group, why it does not appear in output ? Commented Mar 4, 2014 at 7:59
  • Oops, My mistake, it should, correcting... Commented Mar 4, 2014 at 8:01
  • I think it is still wrong. Why "B" gets [2, 3, 4]? Commented Mar 4, 2014 at 8:02

2 Answers 2

1

Try this:

var data = [{
    "grp": ["A", "B"],
    "val": [1, 2, 3]
}, {
    "grp": ["A", "B"],
    "val": [2, 3, 4]
}, {
    "grp": ["A", "C"],
    "val": [1, 3, 5]
}, {
    "grp": ["B", "Y"],
    "val": [1, 3, 2]
}]

// create an object to hold the revised structured data
var newData = {};
_.map(data, function (obj, key) {
    // check whether object is present or not
    if (_.isUndefined(newData[obj.grp[0]])) { //if object is undefined
        newData[obj.grp[0]] = {};
        newData[obj.grp[0]][obj.grp[1]] = [obj.val]; // add an array to second child of grp
    } else { // if object already exists
        // check whether second child of grp is present
        if (_.isUndefined(newData[obj.grp[0]][obj.grp[1]])) { // if not present - create an associated array
            newData[obj.grp[0]][obj.grp[1]] = [obj.val];
        } else { // if present - add value to it
            newData[obj.grp[0]][obj.grp[1]].push(obj.val);
        }
    }
});

// print on console window
console.log(newData);

JSFiddle link: http://jsfiddle.net/4G57E/

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

3 Comments

Same result. Works, but not for dynamic groups.
Could you provide an example what specific result do you need when you have 3 elements in grp.
just same as it is with two levels. for three, the vals come under third nested object. Updated question. I know this is stupid data structure, but can't help it. I am getting input as I shown in the question, and need to display the grouped data.
0
var out = {};
_.each(data,function(item)
       {
           var firstKey = item['grp'][0];
           var secondKey = item['grp'][1];
           out[firstKey] = out[firstKey] || {};
           out[firstKey][secondKey] = out[firstKey][secondKey] || [];
           out[firstKey][secondKey].push(item['val']);
       });

demo:http://jsfiddle.net/HJngC/2/

5 Comments

Thanks. It works for this very specific case, but the length of grp is not fixed, it can be 1, 2 or 3.
@Салман Sorry, that was not part of the actual question.
What! I mentioned it "grp array can be have maximum of 3 elements.". Anyways, thanks for help, I'll figure out how can I make it dynamic.
@Салман , Sorry I missed that part.You can easily do that with a small loop to make it dynamic.
@DhruvPathak Not enough underscore, though :p

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.