UNPKG

@aximario/json-tree

Version:

把扁平化的数据转换成树形结构的JSON,把树形JSON扁平化

106 lines (97 loc) 3.02 kB
import { ConstructOptions, DestructOptions, DestructOptionsMode, NodeType, } from './index.interface' /** * According to the configured props id and pid and children * build each node into one or more trees */ export function construct(nodes: any[], config?: ConstructOptions) { const id = (config && config.id) || 'id' const pid = (config && config.pid) || 'pid' const children = (config && config.children) || 'children' const idMap: any = {} const jsonTree: any[] = [] nodes.forEach(v => { v && v[id] && (idMap[v[id]] = v) }) nodes.forEach(v => { if (v && v[id]) { let parent = idMap[v[pid]] if (parent) { !parent[children] && (parent[children] = []) parent[children].push(v) } else { jsonTree.push(v) } } }) return jsonTree } /** * According to the configured id and pid split the tree into nodes */ export function destruct(forest: object[] | object, config?: DestructOptions) { const id = (config && config.id) || 'id' const pid = (config && config.pid) || 'pid' const children = (config && config.children) || 'children' const mode = (config && config.mode) || DestructOptionsMode.all function flatTree(tree: object) { const queue = [tree] const result = [] while (queue.length > 0) { let currentNode: any = queue.shift() if (currentNode.hasOwnProperty(id)) { let type = NodeType.leaf if (currentNode.hasOwnProperty(pid) && Boolean(currentNode[pid])) { if (currentNode[children] && currentNode[children].length) { type = NodeType.branch } } else { type = NodeType.root } if (type === NodeType.root) { currentNode = { ...currentNode, [pid]: null } } if (type === NodeType.root || type === NodeType.branch) { if (Array.isArray(currentNode[children]) && currentNode[children].length > 0) { currentNode[children].forEach((v: any) => { v && queue.push({ ...v, [pid]: currentNode[id] }) }) } } delete currentNode[children] if (mode === DestructOptionsMode.all) { result.push(currentNode) } if (mode === DestructOptionsMode.branch && type === NodeType.branch) { result.push(currentNode) } if (mode === DestructOptionsMode.leaf && type === NodeType.leaf) { result.push(currentNode) } if ( mode === DestructOptionsMode.nonleaf && (type === NodeType.root || type === NodeType.branch) ) { result.push(currentNode) } if (mode === DestructOptionsMode.root && type === NodeType.root) { result.push(currentNode) } } } return result } if (Array.isArray(forest)) { return forest.map(v => flatTree(v)).reduce((pre, cur) => pre.concat(cur), []) } else { return flatTree(forest) } } export default { construct, destruct, }