UNPKG

es-grid-template

Version:

es-grid-template

77 lines (76 loc) 2.26 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = buildTree; var _others = require("./others"); /** * Builds a tree structure from an array of objects based on `idProp` and `parentIdProp`. * When A[parentIdProp] === B[idProp], object A will be moved to B's `children`. * If an object's `parentIdProp` does not match any other object's `idProp`, * it will be treated as a top-level node in the tree. * @example * const array = [ * { id: 'node-1', parent: 'root' }, * { id: 'node-2', parent: 'root' }, * { id: 'node-3', parent: 'node-2' }, * { id: 'node-4', parent: 'node-2' }, * { id: 'node-5', parent: 'node-4' }, * ] * const tree = buildTree('id', 'parent', array) * expect(tree).toEqual([ * { id: 'node-1', parent: 'root' }, * { * id: 'node-2', * parent: 'root', * children: [ * { id: 'node-3', parent: 'node-2' }, * { * id: 'node-4', * parent: 'node-2', * children: [{ id: 'node-5', parent: 'node-4' }], * }, * ], * }, * ]) */ function buildTree(idProp, parentIdProp, items) { const wrapperMap = new Map(); const ensure = id => { if (wrapperMap.has(id)) { return wrapperMap.get(id); } // @ts-ignore const wrapper = { id, parent: null, item: null, children: [] }; wrapperMap.set(id, wrapper); return wrapper; }; for (const item of items) { const parentWrapper = ensure(item[parentIdProp]); const itemWrapper = ensure(item[idProp]); itemWrapper.parent = parentWrapper; parentWrapper.children.push(itemWrapper); itemWrapper.item = item; } const topLevelWrappers = (0, _others.flatMap)(Array.from(wrapperMap.values()).filter(wrapper => wrapper.parent == null), wrapper => wrapper.children); return unwrapRecursively(topLevelWrappers); function unwrapRecursively(wrapperArray) { const result = []; for (const wrapper of wrapperArray) { if (wrapper.children.length === 0) { result.push(wrapper.item); } else { result.push({ ...wrapper.item, children: unwrapRecursively(wrapper.children) }); } } return result; } }