class Tree { constructor(list = [], config) { this.config = { key: 'id', parent: 'parentId', children: 'children', ...config } this.list = list if (Array.isArray(list)) this.tree = this.arr2tree(list) } arr2tree(list) { const {key, parent, children} = this.config const result = [] this.map = {} const ids = list?.map(e => `#${e[key]}#`)?.toString() for (const e of list) { const id = e[key], pid = e[parent] this.map[id] = {...e, [children]: [this.map[id]?.[children]].flat().filter(Boolean)} const treeItem = this.map[id] if (!!pid && ids.indexOf(`#${pid}#`) > -1) { if (!this.map[pid]) { this.map[pid] = { children: [] } } this.map[pid].children.push(treeItem) } else result.push(treeItem) } const removeNullChildren = node => { if (node[children] && node[children].length > 0) { node[children].map(c => removeNullChildren(c)) } else delete node[children] } result.forEach(removeNullChildren) return result } root(id) { return this.map[id] } find(id) { return this.map[id] } every(cb) { const iterate = list => { list?.map(e => { cb(e) iterate(e.children) }) } iterate(this.tree) } } export default Tree