-
Notifications
You must be signed in to change notification settings - Fork 0
/
optimized.ts
76 lines (73 loc) · 2.24 KB
/
optimized.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/**
* 目的の値にたどるために必要な経路を配列で出力する関数
* 目的の値がない場合はnullを返す
*/
function getPath(
obj: any,
targetValue: string | number,
path: (string | number)[] = []
): (string | number)[] | null {
if (Array.isArray(obj)) {
for (let i = 0; i < obj.length; i++) {
const newPath = [...path, i]; // 配列のインデックスを数値として保存します。
const result = getPath(obj[i] as any, targetValue, newPath);
// パスが見つかった場合、そのパスを返し、探索を終了します。
if (result) {
return result;
}
}
} else {
for (const key in obj) {
const newPath = [...path, isNaN(parseInt(key)) ? key : parseInt(key)]; // キーが数値であればparseInt()で変換し、そうでなければそのまま保存します。
if (typeof obj[key] === "string" && obj[key] === targetValue) {
return newPath;
}
if (typeof obj[key] === "number" && obj[key] === targetValue) {
return newPath;
}
if (typeof obj[key] === "object") {
const result = getPath(obj[key] as any, targetValue, newPath);
// パスが見つかった場合、そのパスを返し、探索を終了します。
if (result) {
return result;
}
}
}
}
return null;
}
// 使用例
const obj = [
{
level1: {
key1: "value1",
level2: {
key2: "value2",
level3: [
"element1",
"element2",
{
key3: "value3",
level4: {
key4: "value4",
level5: [
"element3",
"element1",
{
key5: "value5",
},
],
},
},
],
},
},
},
{ text: "value1next", value: 114514 },
];
// 'c'というキーへのパスを取得し、コンソールに出力します。
console.log(getPath(obj, "value5")); // ['a', 'b', 'c']
console.log(getPath(obj, "element4")); // ['a', 'b', 'c']
console.log(getPath(obj, "element1")); // ['a', 'b', 'c']
console.log(getPath(obj, "value1next")); // ['a', 'b', 'c']
console.log(getPath(obj, 114514)); // ['a', 'b', 'c']