JavaScript 階層構造JSONから値を検索して要素を取得

> JSONは、配列・オブジェクトではないよ。教えてもらったので、ちょっと修正。2022/10/11

以下のような階層構造JSONから"003.txt" を検索して、

![Image 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703491/110af8b2-ec47-f0d9-5add-56c1d2ac9db8.png)

↓コレとか、
```
{"label":"003.txt","path":"D:\\000\\001\\002\\003\\003.txt"}
```
↓コレを取得
```
[
    {
        "label": "003.txt",
        "path": "D:\\000\\001\\002\\003\\003.txt"
    },
    {
        "label": "003.txt",
        "path": "D:\\000\\003.txt"
    }
]
```
## 階層構造JSON
```javascript:階層構造JSON
let json = '[
    {
        "label": "000.txt",
        "path": "D:\\000\\000.txt"
    },
    {
        "label": "001",
        "path": "D:\\000\\001",
        "children": [
            {
                "label": "000.txt",
                "path": "D:\\000\\001\\000.txt"
            },
            {
                "label": "001.txt",
                "path": "D:\\000\\001\\001.txt"
            },
            {
                "label": "002",
                "path": "D:\\000\\001\\002",
                "children": [
                    {
                        "label": "002-1.txt",
                        "path": "D:\\000\\001\\002\\002-1.txt"
                    },
                    {
                        "label": "002-2.txt",
                        "path": "D:\\000\\001\\002\\002-2.txt"
                    },
                    {
                        "label": "002.txt",
                        "path": "D:\\000\\001\\002\\002.txt"
                    },
                    {
                        "label": "003",
                        "path": "D:\\000\\001\\002\\003",
                        "children": [
                            {
                                "label": "003.txt",
                                "path": "D:\\000\\001\\002\\003\\003.txt"
                            }
                        ]
                    }
                ]
            }
        ]
    },
    {
        "label": "001-1",
        "path": "D:\\000\\001-1",
        "children": [
            {
                "label": "001-1.txt",
                "path": "D:\\000\\001-1\\001-1.txt"
            }
        ]
    },
    {
        "label": "003.txt",
        "path": "D:\\000\\001\\002\\003\\003.txt"
    }
]'
```

## 完全一致 最初出現のみ取得

let tree = JSON.parse(json) 

- tree　　　　　//階層構造 配列
- targetKey　　　//検索対象のキー
- searchValue　　//検索値
- childrenKey　　//子要素のキー

```JavaScript:GetElement (tree, targetKey, searchValue, childrenKey)
const GetElement = (tree, targetKey, searchValue, childrenKey) => {
    let data = null;
    for (const i in tree) {
        //console.log(tree[i]);
        if (tree[i][targetKey] == searchValue) {
            data = tree[i];
            break;
        }
        if (tree[i][childrenKey]) {
            data = GetElement(tree[i][childrenKey], targetKey, searchValue, childrenKey);
        }
        if (data) {
            break;
        }
    }
    return data;
}
```
### 使用例
```JavaScript
GetElement(tree, 'label', "003.txt", 'children')
```
```json:結果
{"label":"003.txt","path":"D:\\000\\001\\002\\003\\003.txt"}
```

## 完全一致 一致したすべての要素を取得

```javaScript:GetElementList (tree, targetKey, searchValue, childrenKey)
GetElementList = (tree, targetKey, searchValue, childrenKey) => {
    let array = [];
    const GetElement = (tree, targetKey, searchValue, childrenKey) => {
        for (const i in tree) {
            if (tree[i][targetKey] == searchValue) {
                array.push(tree[i]);
            }
            if (tree[i][childrenKey]) {
                GetElement(tree[i][childrenKey], targetKey, searchValue, childrenKey);
            }
        }
    }
    GetElement(tree, targetKey, searchValue, childrenKey)
    return array;
}
GetElementList(tree, 'label', "003.txt", 'children')
```

```javaScript:使用例
GetElementList(tree, 'label', "003.txt", 'children')
```
```json:結果
[
    {
        "label": "003.txt",
        "path": "D:\\000\\001\\002\\003\\003.txt"
    },
    {
        "label": "003.txt",
        "path": "D:\\000\\003.txt"
    }
]
```

## 検索値を含む要素を全て取得

```javascript:GetElementListIncludes (tree, targetKey, searchValue, childrenKey)
const GetElementListIncludes = (tree, targetKey, searchValue, childrenKey) => {
    let array = [];
    const GetElement = (tree, targetKey, searchValue, childrenKey) => {
        for (const i in tree) {
            if (tree[i][targetKey].includes(searchValue)) {
                array.push(tree[i]);
            }
            if (tree[i][childrenKey]) {
                GetElement(tree[i][childrenKey], targetKey, searchValue, childrenKey);
            }
        }
    }
    GetElement(tree, targetKey, searchValue, childrenKey)
    return array;
}
```
```javaScript:使用例
GetElementListIncludes(tree, 'label', "1.txt", 'children')
```
```json:結果
[
    {
        "label": "001.txt",
        "path": "D:\\000\\001\\001.txt"
    },
    {
        "label": "002-1.txt",
        "path": "D:\\000\\001\\002\\002-1.txt"
    },
    {
        "label": "001-1.txt",
        "path": "D:\\000\\001-1\\001-1.txt"
    }
]
```