performant-array-to-tree
Advanced tools
Comparing version 1.6.0 to 1.7.0
@@ -16,2 +16,3 @@ export interface Item { | ||
childrenField: string; | ||
throwIfOrphans: boolean; | ||
} | ||
@@ -18,0 +19,0 @@ /** |
@@ -19,2 +19,3 @@ "use strict"; | ||
childrenField: 'children', | ||
throwIfOrphans: false, | ||
}; | ||
@@ -27,7 +28,11 @@ /** | ||
if (config === void 0) { config = {}; } | ||
var _d; | ||
var conf = __assign(__assign({}, defaultConfig), config); | ||
// the resulting unflattened tree | ||
var rootItems = []; | ||
// stores all already processed items with ther ids as key so we can easily look them up | ||
// stores all already processed items with their ids as key so we can easily look them up | ||
var lookup = {}; | ||
// stores all item ids that have not been added to the resulting unflattened tree yet | ||
// this is an opt-in property, since it has a slight runtime overhead | ||
var orphanIds = config.throwIfOrphans ? new Set() : null; | ||
// idea of this loop: | ||
@@ -46,2 +51,6 @@ // whenever an item has a parent, but the parent is not yet in the lookup object, we store a preliminary parent | ||
} | ||
// if we track orphans, delete this item from the orphan set if it is in it | ||
if (orphanIds) { | ||
orphanIds.delete(parentId); | ||
} | ||
// add the current item's data to the item in the lookup table | ||
@@ -65,2 +74,6 @@ if (conf.dataField) { | ||
lookup[parentId] = (_c = {}, _c[conf.childrenField] = [], _c); | ||
// if we track orphans, add the generated parent to the orphan list | ||
if (orphanIds) { | ||
orphanIds.add(parentId); | ||
} | ||
} | ||
@@ -71,2 +84,7 @@ // add the current item to the parent | ||
} | ||
if ((_d = orphanIds) === null || _d === void 0 ? void 0 : _d.size) { | ||
throw new Error("The items array contains orphans that point to the following parentIds: " + | ||
("[" + Array.from(orphanIds) + "]. These parentIds do not exist in the items array. Hint: prevent orphans to result ") + | ||
"in an error by passing the following option: { throwIfOrphans: false }"); | ||
} | ||
return rootItems; | ||
@@ -73,0 +91,0 @@ } |
@@ -1,1 +0,1 @@ | ||
"use strict";var __assign=this&&this.__assign||function(){return(__assign=Object.assign||function(e){for(var r,a=1,i=arguments.length;a<i;a++)for(var t in r=arguments[a])Object.prototype.hasOwnProperty.call(r,t)&&(e[t]=r[t]);return e}).apply(this,arguments)};Object.defineProperty(exports,"__esModule",{value:!0});var defaultConfig={id:"id",parentId:"parentId",dataField:"data",childrenField:"children"};function arrayToTree(e,r){var a,i,t;void 0===r&&(r={});for(var n=__assign(__assign({},defaultConfig),r),d=[],l={},s=0,o=e;s<o.length;s++){var c=o[s],p=c[n.id],h=c[n.parentId];Object.prototype.hasOwnProperty.call(l,p)||(l[p]=((a={})[n.childrenField]=[],a)),n.dataField?l[p][n.dataField]=c:l[p]=__assign(__assign({},c),((i={})[n.childrenField]=l[p][n.childrenField],i));var _=l[p];null==h||""===h?d.push(_):(Object.prototype.hasOwnProperty.call(l,h)||(l[h]=((t={})[n.childrenField]=[],t)),l[h][n.childrenField].push(_))}return d}exports.arrayToTree=arrayToTree; | ||
"use strict";var __assign=this&&this.__assign||function(){return(__assign=Object.assign||function(r){for(var e,t=1,a=arguments.length;t<a;t++)for(var n in e=arguments[t])Object.prototype.hasOwnProperty.call(e,n)&&(r[n]=e[n]);return r}).apply(this,arguments)};Object.defineProperty(exports,"__esModule",{value:!0});var defaultConfig={id:"id",parentId:"parentId",dataField:"data",childrenField:"children",throwIfOrphans:!1};function arrayToTree(r,e){var t,a,n;void 0===e&&(e={});for(var i=__assign(__assign({},defaultConfig),e),o=[],s={},l=e.throwIfOrphans?new Set:null,d=0,h=r;d<h.length;d++){var p=h[d],c=p[i.id],f=p[i.parentId];Object.prototype.hasOwnProperty.call(s,c)||(s[c]=((t={})[i.childrenField]=[],t)),l&&l.delete(f),i.dataField?s[c][i.dataField]=p:s[c]=__assign(__assign({},p),((a={})[i.childrenField]=s[c][i.childrenField],a));var u=s[c];null==f||""===f?o.push(u):(Object.prototype.hasOwnProperty.call(s,f)||(s[f]=((n={})[i.childrenField]=[],n),l&&l.add(f)),s[f][i.childrenField].push(u))}if(null!==l&&void 0!==l&&l.size)throw new Error("The items array contains orphans that point to the following parentIds: ["+Array.from(l)+"]. These parentIds do not exist in the items array. Hint: prevent orphans to result in an error by passing the following option: { throwIfOrphans: false }");return o}exports.arrayToTree=arrayToTree; |
@@ -199,2 +199,26 @@ "use strict"; | ||
}); | ||
it('should not throw if orphans exist but throwIfOrphans is false', function () { | ||
chai_1.expect(arrayToTree_1.arrayToTree([ | ||
{ id: '4', parentId: null, custom: 'abc' }, | ||
{ id: '31', parentId: '4', custom: '12' }, | ||
{ id: '418', parentId: '6', custom: 'ü' }, | ||
])).to.deep.equal([ | ||
{ | ||
data: { id: '4', parentId: null, custom: 'abc' }, children: [ | ||
{ data: { id: '31', parentId: '4', custom: '12' }, children: [] }, | ||
], | ||
}, | ||
]); | ||
}); | ||
it('should throw if orphans exist and throwIfOrphans is true', function () { | ||
chai_1.expect(function () { return arrayToTree_1.arrayToTree([ | ||
{ id: '4', parentId: null, custom: 'abc' }, | ||
{ id: '31', parentId: '4', custom: '12' }, | ||
{ id: '418', parentId: '6', custom: 'ü' }, | ||
{ id: '419', parentId: '418', custom: 'ü' }, | ||
{ id: '420', parentId: '7', custom: 'ü' }, | ||
], { throwIfOrphans: true }); }).to.throw('The items array contains orphans that point to the following parentIds: [6,7]. ' + | ||
'These parentIds do not exist in the items array. ' + | ||
'Hint: prevent orphans to result in an error by passing the following option: { throwIfOrphans: false }'); | ||
}); | ||
it('should work with empty inputs', function () { | ||
@@ -201,0 +225,0 @@ chai_1.expect(arrayToTree_1.arrayToTree([])).to.deep.equal([]); |
{ | ||
"name": "performant-array-to-tree", | ||
"version": "1.6.0", | ||
"version": "1.7.0", | ||
"description": "Converts an array of items with ids and parent ids to a nested tree in a performant `O(n)` way. Runs in browsers and node.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -66,2 +66,3 @@ # Performant array to tree | ||
- `dataField`: key which will contain all properties/data of the original items. Set to null if you don't want a container. Default: `"data"` | ||
- `throwIfOrphans`: option to throw an error if the array of items contains one or more items that have no parents in the array. This option has a small runtime penalty, so it's disabled by default. When enabled, the function will throw an error containing the parentIds that were not found in the items array. When disabled, the function will just ignore orphans and not add them to the tree. Default: `false` | ||
@@ -68,0 +69,0 @@ Example: |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
44252
351
129