# nest.js A multi-level [groupBy](http://underscorejs.org/#groupBy) for arrays inspired by D3's [nest](https://github.com/mbostock/d3/wiki/Arrays#-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](http://jsfiddle.net/V7an5/3/) for live demo. ## Implementation Depends on lodash's [groupBy](http://lodash.com/docs#groupBy) and [mapValues](http://lodash.com/docs#mapValues): ```js _ = 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; ``` ## Usage Input data to be nested: ```js 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: ```js var byType = function(d) { return d.type; }; var byColor = function(d) { return d.color; }; var byQuantity = function(d) { return d.quantity; }; ``` ## First Example Expected output when grouping by `color` and `quantity`: ```js 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: ```js deepEqual(nest(data, ['color', 'quantity']), expected); ``` Nest by key functions: ```js deepEqual(nest(data, [byColor, byQuantity]), expected); ``` ## Second Example Expected output when grouping by `type` and `color`: ```js 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: ```js deepEqual(nest(data, ['type', 'color']), expected); ``` Nest by key functions: ```js deepEqual(nest(data, [byType, byColor]), expected); ```