Skip to content

Commit 2bdd19f

Browse files
authored
feat: create getChildPaths API (#8)
1 parent 031f5f3 commit 2bdd19f

File tree

4 files changed

+102
-2
lines changed

4 files changed

+102
-2
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ getChildByPaths("a/b", "number"); // ReturnType: NumberValueNode | undefined
154154

155155
#### `move(from: string, to: string, kind: string): boolean`
156156

157+
#### `getChildPaths(kind: string): string[]`
158+
157159
## LICENCE
158160

159161
[@himenon/path-oriented-data-structure](https://github.com/Himenon/path-oriented-data-structure)・MIT

src/Operator.ts

+21-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import type { Component, HierarchicalData } from "./types";
1+
import type { Component, Children, HierarchicalData } from "./types";
22
import { Tree } from "./Tree";
3-
import { split } from "./Utils";
3+
import { split, splitKey } from "./Utils";
44

55
export class Operator<TreeKind extends string> {
66
private tree: Tree<TreeKind>;
@@ -93,4 +93,23 @@ export class Operator<TreeKind extends string> {
9393
}
9494
return false;
9595
}
96+
97+
private getChildPaths(kind: string, children: Children, parentPath: string): string[] {
98+
let pathArray: string[] = [];
99+
Object.entries(children).forEach(([key, child]) => {
100+
const subChildren = child.getChildren();
101+
const [, pathName] = splitKey(key);
102+
const nextPath = [parentPath, pathName].join(this.delimiter).replace(/\/$/, "");
103+
if (subChildren) {
104+
pathArray = pathArray.concat(this.getChildPaths(kind, subChildren, nextPath));
105+
} else if (child.kind === kind) {
106+
pathArray.push(nextPath);
107+
}
108+
});
109+
return pathArray;
110+
}
111+
112+
public getNodePaths(kind: string): string[] {
113+
return this.getChildPaths(kind, this.tree.getChildren(), this.tree.name);
114+
}
96115
}

src/Utils.ts

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ export const generateKey = (kind: string, name: string): string => {
22
return `${kind}:${name}`;
33
};
44

5+
export const splitKey = (key: string): string[] => {
6+
return key.split(":");
7+
};
8+
59
export const split = (p: string, delimiter: string): string[] => {
610
const array = [];
711
for (const seg of p.split(delimiter)) {
+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { Node } from "../Node";
2+
import { Operator } from "../Operator";
3+
import { genTestName } from "./tools";
4+
import { treeKind } from "./sample";
5+
6+
describe("Get Child Paths", () => {
7+
test(genTestName("", 0), () => {
8+
const operator = new Operator(treeKind);
9+
expect(operator.getNodePaths("")).toStrictEqual([]);
10+
expect(operator.getNodePaths("a")).toStrictEqual([]);
11+
expect(operator.getNodePaths("b")).toStrictEqual([]);
12+
expect(operator.getNodePaths("c")).toStrictEqual([]);
13+
});
14+
15+
test(genTestName("./a", 1), () => {
16+
const operator = new Operator(treeKind);
17+
const node1 = new Node("node", "b");
18+
operator.set("./a", node1);
19+
console.log(operator.getHierarchy());
20+
expect(operator.getNodePaths("node")).toStrictEqual(["./a"]);
21+
});
22+
test(genTestName("./a", 2), () => {
23+
const operator = new Operator(treeKind);
24+
const node1 = new Node("node1", "b");
25+
const node2 = new Node("node2", "c");
26+
operator.set("./a", node1);
27+
operator.set("./a", node2);
28+
expect(operator.getNodePaths("node1")).toStrictEqual(["./a"]);
29+
expect(operator.getNodePaths("node2")).toStrictEqual(["./a"]);
30+
});
31+
test(genTestName("./a/b", 1), () => {
32+
const operator = new Operator(treeKind);
33+
const node1 = new Node("node", "hello");
34+
operator.set("./a/b", node1);
35+
expect(operator.getNodePaths("node")).toStrictEqual(["./a/b"]);
36+
});
37+
test(genTestName("./a/b", 2), () => {
38+
const operator = new Operator(treeKind);
39+
const node1 = new Node("node1", "hello");
40+
const node2 = new Node("node2", "hello");
41+
operator.set("./a/b", node1);
42+
operator.set("./a/b", node2);
43+
expect(operator.getNodePaths("node1")).toStrictEqual(["./a/b"]);
44+
expect(operator.getNodePaths("node2")).toStrictEqual(["./a/b"]);
45+
});
46+
test(genTestName("./a/b/c", 1), () => {
47+
const operator = new Operator(treeKind);
48+
const node1 = new Node("node", "hello");
49+
operator.set("./a/b/c", node1);
50+
expect(operator.getNodePaths("node")).toStrictEqual(["./a/b/c"]);
51+
});
52+
test(genTestName("./a/b/c", 3), () => {
53+
const operator = new Operator(treeKind);
54+
const node_a1 = new Node("node-A", "hello");
55+
const node_ab2 = new Node("node-B", "world");
56+
const node_abc3 = new Node("node-C", "!");
57+
operator.set("./a", node_a1);
58+
operator.set("./a/b", node_ab2);
59+
operator.set("./a/b/c", node_abc3);
60+
expect(operator.getNodePaths("node-A")).toStrictEqual(["./a"]);
61+
expect(operator.getNodePaths("node-B")).toStrictEqual(["./a/b"]);
62+
expect(operator.getNodePaths("node-C")).toStrictEqual(["./a/b/c"]);
63+
});
64+
65+
test(genTestName("multi paths", 3), () => {
66+
const operator = new Operator(treeKind);
67+
const node_a1 = new Node("node", "hello");
68+
const node_ab2 = new Node("node", "world");
69+
const node_abc3 = new Node("node", "!");
70+
operator.set("./a", node_a1);
71+
operator.set("./a/b", node_ab2);
72+
operator.set("./a/b/c", node_abc3);
73+
expect(operator.getNodePaths("node")).toStrictEqual(["./a", "./a/b", "./a/b/c"]);
74+
});
75+
});

0 commit comments

Comments
 (0)