没测过,不过思路应该没问题
type Tree = Array<TreeItem>
type RawNode = {
id: string
pid?: string
prev_id?: string
next_id?: string
[key: string]: any
}
interface LinkedNode<E> {
node: E,
firstChild?: LinkedNode<E>
nextNode?: LinkedNode<E>
}
function toTree<E, K, T>(elements: E[],
getId: (element: E) => K,
getParentId: (element: E) => K | undefined,
getPrevId: (element: E) => K | undefined,
createTreeNode: (element: E) => T,
appendChild: (parent: T, child: T) => void): T[] {
const linkedNodes: Map<K, LinkedNode<T>> = new Map();
elements.forEach(element => linkedNodes.set(getId(element), {node: createTreeNode(element)}));
const rootLinkedNode: LinkedNode<T>[] = []
for (let element of elements) {
const parentId = getParentId(element);
const id = getId(element)
const linkedNode = linkedNodes.get(id)!
if (parentId) {
const prevId = getPrevId(element)
if (prevId) {
const pervLinkedNode = linkedNodes.get(prevId);
console.assert(!!pervLinkedNode, `${prevId} is not found`)
pervLinkedNode!.nextNode = linkedNode
} else {
const parentLinkedNode = linkedNodes.get(parentId);
console.assert(!!parentLinkedNode, `${parentId} is not found`)
parentLinkedNode!.firstChild = linkedNode
}
} else {
rootLinkedNode.push(linkedNode)
}
}
for (let linkedNode of linkedNodes.values()) {
for (let child = linkedNode.firstChild; child; child = child.nextNode) {
appendChild(linkedNode.node, child.node)
}
}
return rootLinkedNode.map(linkedNode => linkedNode.node)
}
function test(){
const raw_nodes = [/**/]
const rootNodes :Tree = toTree<RawNode, string, RawNode>(raw_nodes,
node =>
node.id,
node => node.pid,
node => node.prev_id,
node => {
node.children = [];
return node;
},
(parent, child) => parent.children.push(child)
)
console.info(rootNodes)
}