Using Underscore.js, I'm trying to group a list of items multiple times, ie
Group by SIZE then for each SIZE, group by CATEGORY...
http://jsfiddle.net/rickysullivan/WTtXP/1/
Ideally, I'd like to have a function or extend _.groupBy()
so that you can throw an array at it with the paramaters to group by.
var multiGroup = ['size', 'category'];
Probably could just make a mixin...
_.mixin({
groupByMulti: function(obj, val, arr) {
var result = {};
var iterator = typeof val == 'function' ? val : function(obj) {
return obj[val];
};
_.each(arr, function(arrvalue, arrIndex) {
_.each(obj, function(value, objIndex) {
var key = iterator(value, objIndex);
var arrresults = obj[objIndex][arrvalue];
if (_.has(value, arrvalue))
(result[arrIndex] || (result[arrIndex] = [])).push(value);
My head hurts, but I think some more pushing needs to go here...
});
})
return result;
}
});
properties = _.groupByMulti(properties, function(item) {
var testVal = item["size"];
if (parseFloat(testVal)) {
testVal = parseFloat(item["size"])
}
return testVal
}, multiGroup);
Here is an easy to understand function.
How about this rather simple hack?
A simple recursive implementation:
Demo in your jsfiddle
I think @Bergi's answer can be streamlined a bit by utilizing Lo-Dash's
mapValues
(for mapping functions over object values). It allows us to group the entries in an array by multiple keys in a nested fashion:I renamed the method to
nest
because it ends up serving much the same role served by D3's nest operator. See this gist for details and this fiddle for demonstrated usage with your example.lodash nest groupby
Grouping by a composite key tends to work better for me in most situations:
Demo using OP's fiddle
Mixin
An example with lodash and mixin