feat: add circular reference to parents of nodes

pull/4377/head
Arman Ozak 5 years ago
parent 66111b9afa
commit c72bcf48f4

@ -1,4 +1,4 @@
import { createTreeFromList, TreeNode } from '../utils/tree-utils';
import { BaseTreeNode, createTreeFromList, TreeNode } from '../utils/tree-utils';
const LIST_1 = [
{ id: 1, pid: null },
@ -46,23 +46,32 @@ describe('Tree Utils', () => {
${LIST_2} | ${TREE_2}
${LIST_3} | ${TREE_3}
`('should return $expected when given $list', ({ list, expected }: TestCreateTreeFromList) => {
expect(
createTreeFromList(
list,
x => x.id,
x => x.pid,
),
).toEqual(expected);
const tree = createTreeFromList(
list,
x => x.id,
x => x.pid,
x => BaseTreeNode.create(x),
);
expect(removeParents(tree)).toEqual(expected);
});
});
});
function removeParents(tree: TreeNode<Model>[]) {
return tree.map(v => {
const { parent, ...node } = v;
node.children = removeParents(node.children);
return node;
});
}
interface TestCreateTreeFromList {
list: ModelA[];
expected: TreeNode<ModelA>[];
list: Model[];
expected: TreeNode<Model>[];
}
interface ModelA {
interface Model {
id: 1;
pid: null;
}

@ -1,19 +1,20 @@
export class TreeNodeFactory<T extends object> {
export class BaseTreeNode<T extends object> {
children: TreeNode<T>[] = [];
isLeaf = true;
parent: TreeNode<T>;
constructor(props: T) {
Object.assign(this, props);
}
static create<T extends object>(props: T) {
return new TreeNodeFactory<T>(props) as TreeNode<T>;
return new BaseTreeNode<T>(props) as TreeNode<T>;
}
}
export function createTreeFromList<T extends object, R extends unknown>(
list: T[],
keySelector: (item: T) => number | string | Symbol,
keySelector: (item: T) => number | string | symbol,
parentKeySelector: typeof keySelector,
valueMapper: (item: T) => R,
) {
@ -27,8 +28,10 @@ export function createTreeFromList<T extends object, R extends unknown>(
if (parentId) {
const parent = map.get(parentId);
if (!parent) return;
(parent as any).children.push(node);
(parent as any).isLeaf = false;
(node as any).parent = parent;
} else {
tree.push(node);
}
@ -39,7 +42,7 @@ export function createTreeFromList<T extends object, R extends unknown>(
export function createMapFromList<T extends object, R extends unknown>(
list: T[],
keySelector: (item: T) => number | string | Symbol,
keySelector: (item: T) => number | string | symbol,
valueMapper: (item: T) => R,
) {
type Key = ReturnType<typeof keySelector>;
@ -54,6 +57,7 @@ export type TreeNode<T extends object> = {
} & {
children: TreeNode<T>[];
isLeaf: boolean;
parent?: TreeNode<T>;
};
type NodeValue<T extends object, F extends (...args: any) => any> = F extends undefined

Loading…
Cancel
Save