何千行ものJSONから要素を抽出する方法は？その答えは... 🧐


JSONは、**J**Java**S**Script **O**bject **N**otationの略で、2001年にDouglas Crockfordによって発見・定義されました。22歳の大学生が卒業を控える中、22歳のJSONはインターネットのデータ交換の標準のひとつとなり、開発者にもよく知られている。

開発者の一人として、私は数え切れないほどのJSONファイルを読んできました。JSONは太かったり細かったり、長かったり短かったりします。短いJSONは、ブール値だけを含む単純な配列にすることができます：

```json
[true]
```

そして、長いJSONは驚くことに数万行になることもあります：
![](https://he3.app/blogs/json-path/ddaaed11b32a171a95d1fa9f6262662e29689233d7c8751ba4df7ebdb82d46e1.png)  

長いJSONファイルを読むとき、最も一般的な要件は、フィールドの値を抽出したり、配列のオブジェクト値をトラバースすることですが、これらはすべてJSONの川の奥深くに埋もれています。

プログラミングの初心者にとって、最初に考えることは、プログラミングを使って目的のフィールドを取得することでしょう。例えば、次のようなJSON構造があるとします：

```json
{
  "human": {
    "person": {
      "man": [
        {
          "name": "Jack",
          "age": "17"
        },
        {
          "name": "Mike",
          "age": "32"
        },
        {
          "name": "John",
          "age": "23"
        },
        {
          "name": "David",
          "age": "41"
        },
        {
          "name": "Eric",
          "age": "29"
        },
        {
          "name": "Chris",
          "age": "38"
        },
        {
          "name": "Tom",
          "age": "27"
        },
        {
          "name": "Peter",
          "age": "35"
        },
        {
          "name": "Robert",
          "age": "26"
        },
        {
          "name": "Daniel",
          "age": "33"
        }
      ]
    }
  }
}
```

さて、私は `man` 配列のすべての要素の `name` を取得する必要があるので、ぜひこのJSコードを書きましょう：

```js
const nameSet = data.human.person.man.map(manItem => manItem.name)
```

モダンなJavaScriptの構文糖とAPIのおかげで、コードは簡潔なものとなっています。1つはこのコードファイルを保存する必要性、2つはこのコードを実行する環境の必要性、3つはコードの実行結果を印刷または保存する必要性、4つはこのコードを継続的にデバッグして例外やエッジケースなどを処理する必要性など、コードは単純ですが、考慮すべき問題はたくさんあります。

プログラミング初心者は、JSONの値をインデックス化するシナリオはたくさんあるが、不器用なプログラミングは効率的な方法ではないので、現在人気のあるChatGPTに頼りたい、と考え続けている：

- 🧑‍💻 上記のJSON構造を持っていますが、`man`フィールドの下にあるすべての要素の`name`フィールドを抽出するのを手伝ってください上記のJSON構造を持っていますが、`man`フィールドの下にあるすべての要素の `name` フィールドを抽出するのを手伝ってください。.

- 🤖 man` 以下の全要素の `name` フィールドを抽出するのを手伝います、その結果は:<br />Jack<br />Mike,<br />John,<br />David,<br />Eric,<br />Chris,<br />Tom,<br />Peter,<br />Robert,<br />Daniel

プログラミング初心者は、この結果を得て感激しましたが、すぐに別の問題に遭遇しました。ChatGPTの入力ボックスに何万行ものJSONを貼り付けると、すぐにエラーメッセージが表示されましたプログラミングの初心者は、結果を得たことに興奮しましたが、すぐに別の問題に遭遇しました。ChatGPTの入力ボックスに何万行ものJSONを貼り付けると、すぐにエラーメッセージが表示されたのです。:

![](https://he3.app/blogs/json-path/b21381c766ab01c922255155c1f78e33567379376e16cda06603ac89a3b649bc.png)  


強力なChatGPTも、非常に長く複雑なテキストの前では屈服してしまいます。もちろん、分割して入力したり、ChatGPTのAPIをプログラムで呼び出したりという解決策もあります。しかし、これに頼ってしまうと、また振り出しに戻ってしまいます強力なChatGPTも、非常に長く複雑なテキストを前にすると屈服してしまいます。もちろん、分割して入力したり、ChatGPTのAPIをプログラムで呼び出したりという解決策もあります。しかし、これに頼ると、また振り出しに戻ることになります.

では、もっといい方法はないのでしょうか？🧐

その解決策は、**JSON Path**に違いない！He3 JSON Pathツールを例にとって考えてみましょう。前の例から`name`フィールドを取得するには、入力ボックスに`$..name`と入力するだけでよいのです！He3 JSON Pathツールを例にとって説明しましょう。先ほどの例の`name`フィールドを取得するには、入力ボックスに`$..name`と入力すればよい：

![](https://he3.app/blogs/json-path/48bbcde8d0b4c6e3b9e089ae6ac60ee0735b57ffcd04907d2d195d94e9a21c3d.png)  


> JSON Pathツールリンク: [https://t.he3app.com?c9yj](https://t.he3app.com?c9yj)

最初に`$..name`を見たとき、あなたは戸惑うかもしれません。これはどんな構文なのだろう？どのように動作するのでしょうか？

JSON Pathを紹介しましょう：

> JSON Pathは、JSONデータ内の特定の要素を探し出し、抽出するための表現言語です。複雑なJSON構造からデータを簡単に抽出するための簡潔な構文を提供します。

簡単に言うと、JSON PathはMarkdownのようなものです。JSON構造から断片を抽出することができる軽量の構文です。

言語であるJSON Pathは、その構文やキーワードを把握するために一定の学習が必要です。しかし、JSON Pathの学習曲線は急ではありませんので、ご安心ください。一度マスターすれば、特定のキー値の抽出、配列のトラバース、条件による要素のフィルタリング、スライシングなどが可能です。JSONデータを簡単に扱えるようになるのです。

まず、一般的なJSON Pathの構文を紹介しましょう：

- `$`: JSONデータの一番外側の層を表すルートノードです。
- `.`: 子ノード演算子。オブジェクトのプロパティにアクセスするために使用します。
- `[]`: インデックス演算子。配列の要素にアクセスしたり、条件によって要素をフィルタリングするために使用されます。
- `*`: ワイルドカード：任意のプロパティ名や配列のインデックスにマッチさせるために使用されます。
- `..`: 再帰的降順演算子、入れ子構造のすべてのレベルを検索するために使用されます。
- `@`: 現在のノード。フィルタリング条件において、現在のノードを参照するために使用することができる。

例えば、`"god"`というキーと値のペアを追加したとする： 先ほどの JSON の例で、`"god": `キーバリューペアを追加し、JSON Path を使って `god` フィールドを取得したいとすると、`$.god` を使用することができます：

![](https://he3.app/blogs/json-path/89d44088b991c43c4f93591a4a355c62988e6690d56f4e79fed1ce01b896e58a.png)  


.name`については、「JSONデータ内の全レベルの `name` キーの値を返す」という意味であることがわかる。もし、すべての`age`フィールドを取得したいのであれば、`$..age`に変更すればよいのです：

![](/blogs/json-path/68c1497b06b3647b889fee65a96ae42a90ac4668b8fd3e48bcf94e15edf2b22d.png)  


配列 `man` の最初の要素を取得したい場合は、`$.human.person.man[0]` と入力します：

![](https://he3.app/blogs/json-path/0d63d4892acb388b78b18967901fe321c618c1b89172449c907e3658320f344f.png)  


もちろん、再帰的降下演算子を使えば、さらに便利です `$..man[0]`：

![](/blogs/json-path/9a611b39c4937f8d2ad6d232553964f21a0196902c4966c5968e0280ecf65bc5.png)  


インデックス参照演算子 `[]` は、さらに高度な演算が可能です。

例えば、第1、第2、第3の要素を得るには、`$..man[0,1,2]`と入力すればよい：

![](https://he3.app/blogs/json-path/4c1ca968ac81ea533097675b6c7a19c089c7d9603df2c62221d35bc874678db8.png)  


1`, `2`, `3` といった連続した配列要素を取得するには、JSON Path では `[start:end]` という表現がより便利です。上記は、`$..man[0:3]`に変更することができます：


![](https://he3.app/blogs/json-path/5533fe4310cdc90a32263d0d94e18f3a451f187f0836413cd20e5f2f48c715cf.png)  


❗️ なお、`[0,3`という表現は、`start`は含むが`end`は含まない。

また、JSON Pathは2種類の式を提供します：

1. `()`: 条件判定や論理演算に使用される**式**です。括弧の中では、比較演算子（`>`, `<`, `==` など）や論理演算子（`&&`, `||` など）を使って条件を定義することができる。例えば、`(@.length)`は配列の最後の要素を取得することを表しています。

2. `?()`: **フィルタ式**です。?()`では、JavaScriptの任意の正規表現を使って要素をフィルタリングすることができます。このような式はフィルタの内部で計算され、その結果に基づいて現在の要素を選択するか除外するかを決定します。例えば、`[?(@.age > 25)]` は「age」属性に基づいて要素をフィルタリングし、ageが25より大きいものを選択します。

この2つの式を用いることで、データ抽出の精度をさらに向上させることができます。例えば、`man`の最後の要素を取得するには、`$..man[(@.length-1)]`を使用することができます：


![](https://he3.app/blogs/json-path/a0717ee713aa73a4b3eb3025fc5338af2d8896011e5877ad09c5e75de1e911f5.png)  


`@` は現在の要素、`.length` は現在の要素の長さを表すので、`(@.length-1)` は配列の最後の要素を取得するために使用することができる。

man` フィールドで `age` が `33` 以上の人をフィルタリングしたい場合は、`$..man[?(@.age >= 33)]` というフィルタリング式を使用することができます：


![](https://he3.app/blogs/json-path/2e12c15a2cca131ebd0f6578dc2b7d1becce6b78789d2a0d389192f04d9e895d.png)  


以上、一般的に使用されるJSON Pathの構文のほとんどをカバーしました。あまり一般的に使われていない構文については、[JSON Path Plusの実装](https://github.com/JSONPath-Plus/JSONPath)を参照することができます。

> JSON Pathには公式な標準文書がありませんが、広く受け入れられ使用されている実装や文書がいくつかあります。JSON Path Plusはその一つで、He3 JSON PathツールはJSON Path Plusを採用しています。

本題に戻りますが、以下の数万行のJSONの中で：

![](https://he3.app/blogs/json-path/ddaaed11b32a171a95d1fa9f6262662e29689233d7c8751ba4df7ebdb82d46e1.png)  

Ellen Rowland`という名前の`友達`がいるかどうかを確認したい場合は、できます：

![](https://he3.app/blogs/json-path/30176984cc2bb78b47cb19d70621f98ffe5f705b1e42db35c59889d70c47caa1.png)