-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathindex.js
72 lines (59 loc) · 1.75 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
'use strict';
var isArray = require('lodash.isarray');
var assign = require('lodash.assign');
var property = require('nested-property');
var createTree = function(array, rootNodes, customID) {
var tree = [];
for (var rootNode in rootNodes) {
var node = rootNodes[rootNode];
var childNode = array[node[customID]];
if (!node && !rootNodes.hasOwnProperty(rootNode)) {
continue ;
}
if (childNode) {
node.children = createTree(array, childNode, customID);
}
tree.push(node);
}
return tree;
};
var groupByParents = function(array, options) {
return array.reduce(function(prev, item) {
var parentID = property.get(item, options.parentProperty) || options.rootID;
if (parentID && prev.hasOwnProperty(parentID)) {
prev[parentID].push(item);
return prev;
}
prev[parentID] = [item];
return prev;
}, {});
};
/**
* arrayToTree
* Convert a plain array of nodes (with pointers to parent nodes) to a nested
* data structure
*
* @name arrayToTree
* @function
*
* @param {Array} data An array of data
* @param {Object} options An object containing the following fields:
*
* - `parentProperty` (String): A name of a property where a link to
* a parent node could be found. Default: 'parent_id'
* - `customID` (String): An unique node identifier. Default: 'id'
*
* @return {Array} Result of transformation
*/
module.exports = function arrayToTree(data, options) {
options = assign({
parentProperty: 'parent_id',
customID: 'id',
rootID: '0'
}, options);
if (!isArray(data)) {
throw new TypeError('Expected an object but got an invalid argument');
}
var grouped = groupByParents(data, options);
return createTree(grouped, grouped[options.rootID], options.customID);
};