A multi-level groupBy for arrays inspired by D3’s nest operator.
Nesting allows elements in an array to be grouped into a hierarchical tree
structure; think of it like the GROUP BY
operator in SQL, except you can have
multiple levels of grouping, and the resulting output is a tree rather than a
flat table. The levels in the tree are specified by key functions.
See this fiddle for live demo.
Depends on lodash’s groupBy and mapValues:
_ = require('lodash');
var nest = function (seq, keys) {
if (!keys.length)
return seq;
var first = keys[0];
var rest = keys.slice(1);
return _.mapValues(_.groupBy(seq, first), function (value) {
return nest(value, rest)
});
};
module.exports = nest;
Input data to be nested:
var data = [
{ type: "apple", color: "green", quantity: 1000 },
{ type: "apple", color: "red", quantity: 2000 },
{ type: "grape", color: "green", quantity: 1000 },
{ type: "grape", color: "red", quantity: 4000 }
];
Key functions used for grouping criteria:
var byType = function(d) {
return d.type;
};
var byColor = function(d) {
return d.color;
};
var byQuantity = function(d) {
return d.quantity;
};
Expected output when grouping by color
and quantity
:
var expected = {
green: {
"1000": [
{ type: 'apple', color: 'green', quantity: 1000 },
{ type: 'grape', color: 'green', quantity: 1000 }
]
},
red: {
"2000": [
{ type: 'apple', color: 'red', quantity: 2000 }
],
"4000": [
{ type: 'grape', color: 'red', quantity: 4000 }
]
}
};
Nest by key name:
deepEqual(nest(data, ['color', 'quantity']), expected);
Nest by key functions:
deepEqual(nest(data, [byColor, byQuantity]), expected);
Expected output when grouping by type
and color
:
expected = {
apple: {
green: [ { "type": "apple", "color": "green", "quantity": 1000 } ],
red: [ { "type": "apple", "color": "red", "quantity": 2000 } ]
},
grape: {
green: [ { "type": "grape", "color": "green", "quantity": 1000 } ],
red: [ { "type": "grape", "color": "red", "quantity": 4000 } ]
}
};
Nest by key names:
deepEqual(nest(data, ['type', 'color']), expected);
Nest by key functions:
deepEqual(nest(data, [byType, byColor]), expected);