# 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);
```
No comments:
Post a Comment