FileMakerカスタム関数 階層構造JSONから値を検索して要素を取得


## 動作検証
FileMaker Pro 19.5.4

## 階層構造JSON
```json:階層構造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"
            }
        ]
    }
]
```

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

### カスタム関数

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

```java:GetElement ( json ; targetKey ; searchValue ; childrenKey )
While ( 
 [ 
 ~json = json;
 ~targetKey=targetKey;
 ~searchValue=searchValue;
 ~childrenKey=childrenKey;

	~listKey = JSONListKeys ( ~json ; "" );
	~count = ValueCount ( ~listKey ) ; 
	~data = "";
	~n = 1
 ] ; 
 ~n  ≤  ~count ; 
 [
	~val = JSONGetElement ( ~json ; "[" & ~n-1 & "]."  & ~targetKey);
	~children =  JSONGetElement ( ~json ; "[" & ~n-1 & "]." & ~childrenKey );
	~data =List(~data ; 
				If (not IsEmpty( ~children ); 
						GetElement(~children; ~targetKey; ~searchValue; ~childrenKey )
				);
				If ( ~val=~searchValue ; JSONGetElement ( ~json ; "[" & ~n-1 & "]") )
		);
	~n=If ( not IsEmpty(~data) ; ~count+1 ; ~n + 1 )
 ] ;
    ~data
)
```
### 使用例
```java:キー:label, "003.txt"と一致
Let([

json =fmFileExplorer::treeData
; targetKey ="label"
; searchValue ="003.txt"
; childrenKey="children"
];

GetElement ( json ; targetKey ; searchValue ; childrenKey )

)
```
```:結果
{"label":"003.txt","path":"D:\\000\\001\\002\\003\\003.txt"}
```
### 検索対象キーを変更
```java:キー:path, "D:\\000\\001\\002\\002.txt" と一致
Let([

json =fmFileExplorer::treeData
; targetKey ="path"
; searchValue = "D:\\000\\001\\002\\002.txt"
; childrenKey="children"

];

GetElement ( json ; targetKey ; searchValue ; childrenKey )

)
```
```:結果
{"label":"002.txt","path":"D:\\000\\001\\002\\002.txt"}
```

## 完全一致 一致したすべての要素を取得
### カスタム関数
```java:GetElementList ( json ; targetKey ; searchValue ; childrenKey )
While ( 
 [ 
 ~json = json;
 ~targetKey=targetKey;
 ~searchValue=searchValue;
 ~childrenKey=childrenKey;

	~listKey = JSONListKeys ( ~json ; "" );
	~count = ValueCount ( ~listKey ) ; 
	~data = "";
	~n = 1
 ] ; 
 ~n  ≤  ~count ; 
 [
	~val = JSONGetElement ( ~json ; "[" & ~n-1 & "]."  & ~targetKey);
	~children =  JSONGetElement ( ~json ; "[" & ~n-1 & "]." & ~childrenKey );
	~data =List(~data ; 
				If (not IsEmpty( ~children ); 
						GetElementList(~children; ~targetKey; ~searchValue; ~childrenKey )
				);
				If ( ~val=~searchValue ; JSONGetElement ( ~json ; "[" & ~n-1 & "]") )
		);
	~n=~n + 1 
 ] ;
    ~data
)
```
### 使用例

```java:キー:"label", "000.txt"に一致 すべて取得
Let([

json =fmFileExplorer::treeData
; targetKey ="label"
; searchValue = "000.txt"
; childrenKey="children"

];

GetElementList ( json ; targetKey ; searchValue ; childrenKey )

)
```
```:結果
{"label":"000.txt","path":"D:\\000\\000.txt"}
{"label":"000.txt","path":"D:\\000\\001\\000.txt"}
```



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

```java:GetElementListIncludes ( json ; targetKey ; searchValue ; childrenKey )
While ( 
 [ 
 ~json = json;
 ~targetKey=targetKey;
 ~searchValue=searchValue;
 ~childrenKey=childrenKey;

	~listKey = JSONListKeys ( ~json ; "" );
	~count = ValueCount ( ~listKey ) ; 
	~data = "";
	~n = 1
 ] ; 
 ~n  ≤  ~count ; 
 [
	~val = JSONGetElement ( ~json ; "[" & ~n-1 & "]."  & ~targetKey);
	~children =  JSONGetElement ( ~json ; "[" & ~n-1 & "]." & ~childrenKey );
	~data =List(~data ; 
			
				If (not IsEmpty( ~children ); 
						GetElementListIncludes(~children; ~targetKey; ~searchValue; ~childrenKey )
				);
				If (Position ( ~val ; ~searchValue ; 1 ; 1 ) >0 ; JSONGetElement ( ~json ; "[" & ~n-1 & "]") )

		);
	~n=~n + 1 
 ] ;
    ~data
)
```

### 使用例
```java:キー:"label", ".txt"を含む要素を取得
Let([

json =fmFileExplorer::treeData
; targetKey ="label"
; searchValue = ".txt"
; childrenKey="children"

];

GetElementListIncludes ( json ; targetKey ; searchValue ; childrenKey )

)
```
```:結果
{"label":"000.txt","path":"D:\\000\\000.txt"}
{"label":"000.txt","path":"D:\\000\\001\\000.txt"}
{"label":"001.txt","path":"D:\\000\\001\\001.txt"}
{"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.txt","path":"D:\\000\\001\\002\\003\\003.txt"}
{"label":"001-1.txt","path":"D:\\000\\001-1\\001-1.txt"}
```