UNPKG

1.94 kBPlain TextView Raw
1type Node<Payload> = [Payload | undefined, InternalTree<Payload>];
2
3interface InternalTree<Payload> {
4 [name: string]: Node<Payload>;
5}
6
7export default class SymbolTree<Payload, T> {
8 private tree: Node<Payload> = [undefined, {}];
9
10 constructor(private mapper: (t: T) => string) {}
11
12 public set(path: Array<T>, element: Payload | undefined, max?: number): void {
13 let curr = this.tree;
14 const _max = max !== undefined ? max : path.length;
15 for (let i = 0; i < _max; i++) {
16 const n = this.mapper(path[i]);
17 let child: Node<Payload> = curr[1][n];
18 if (!child) {
19 child = [undefined, {}];
20 curr[1][n] = child;
21 }
22 curr = child;
23 }
24 curr[0] = element;
25 }
26
27 public getDefault(
28 path: Array<T>,
29 mkDefaultElement: () => Payload,
30 max?: number
31 ): Payload {
32 return this.get(path, mkDefaultElement, max) as Payload;
33 }
34
35 /**
36 * Returns the payload of the path
37 * If a default element creator is given, it will insert it at the path
38 */
39 public get(
40 path: Array<T>,
41 mkDefaultElement?: () => Payload,
42 max?: number
43 ): Payload | undefined {
44 let curr = this.tree;
45 const _max = max !== undefined ? max : path.length;
46 for (let i = 0; i < _max; i++) {
47 const n = this.mapper(path[i]);
48 let child: Node<Payload> = curr[1][n];
49 if (!child) {
50 if (mkDefaultElement) {
51 child = [undefined, {}];
52 curr[1][n] = child;
53 } else {
54 return undefined;
55 }
56 }
57 curr = child;
58 }
59 if (mkDefaultElement && !curr[0]) {
60 curr[0] = mkDefaultElement();
61 }
62 return curr[0];
63 }
64
65 public delete(path: Array<T>): void {
66 let curr = this.tree;
67 for (let i = 0; i < path.length - 1; i++) {
68 const child = curr[1][this.mapper(path[i])];
69 if (!child) {
70 return;
71 }
72 curr = child;
73 }
74 delete curr[1][this.mapper(path[path.length - 1])];
75 }
76}