JSONataオブジェクト操作チートシート

## JSONataの基本

JSONataの基本的なことは以下がわかりやすいです。
-  [Node-RED LibraryのLearn JSONata with examples](https://flows.nodered.org/flow/29fd01f8a62fec86d875ecbd68001cb0)
- [JSONata本家サイト](https://jsonata.org/)

## 本題: JSONataオブジェクト操作チートシート

Node-REDのフローで役に立つJSONataによるオブジェクト操作のチートシートです（※Beforeの値がmsg.payloadを流れてきた前提）

### 1. オブジェクト内の特定のキー名を変更する

**Before:**

```json
{
  "name": "Alice",
  "age": 30
}
```

**JSONata:**

```jsonata
{
  "fullName": payload.name,
  "age": payload.age
}
```

**After:**

```json
{
  "fullName": "Alice",
  "age": 30
}
```

---

### 2. ネストされたオブジェクトをフラットにする

**Before:**

```json
{
  "name": "Bob",
  "details": {
    "age": 25,
    "city": "New York"
  }
}
```

**JSONata:**

```jsonata
{
  "name": payload.name,
  "age": payload.details.age,
  "city": payload.details.city
}
```

**After:**

```json
{
  "name": "Bob",
  "age": 25,
  "city": "New York"
}
```

---

### 3. 2が配列の場合

**Before:**

```json
[
  {
    "name": "Joe",
    "details": {
      "age": 18,
      "city": "Texas City"
    }  
  },
  {
    "name": "Charlie",
    "details": {
      "age": 22,
      "city": "San Francisco"
    }
  },
  {
    "name": "Diana",
    "details": {
      "age": 28,
      "city": "New York"
    }
  }
]
```

**JSONata:**

```jsonata
payload.{
  "name": name,
  "age": details.age,
  "city": details.city
}
```

**After:**

```json
[
  {
    "name": "Joe",
    "age": 18,
    "city": "Texas City"
  },
  {
    "name": "Charlie",
    "age": 22,
    "city": "San Francisco"
  },
  {
    "name": "Diana",
    "age": 28,
    "city": "New York"
  }
]
```

---

### 4. 配列内のオブジェクトの特定のフィールドだけを抽出する

**Before:**

```json
[
  { 
    "name": "Joe", 
    "age": 18 
  },
  { 
    "name": "Charlie", 
    "age": 22 
  },
  { 
    "name": "Diana", 
    "age": 28 
  }
]
```

**JSONata:**

```jsonata
payload.name
```

**After:**

```json
["Joe", "Charlie", "Diana"]
```

---

### 5. 条件によるフィルタリング

**Before:**

```json
[
  { 
    "name": "Joe", 
    "age": 18 
  },
  { 
    "name": "Charlie", 
    "age": 22 
  },
  { 
    "name": "Diana", 
    "age": 28 
  }
]
```

**JSONata:**

```jsonata
payload[age >= 21]
```

**After:**

```json
[
  {
    "name": "Charlie",
    "age": 22
  },
  {
    "name": "Diana",
    "age": 28
  }
]
```

---

### 6. 配列内のオブジェクトのキーを別の値に変換する

**Before:**

```json
[
  { "oldKey": "value1" },
  { "oldKey": "value2" }
]
```

**JSONata:**

```jsonata
payload.{ "newKey": oldKey }
```

**After:**

```json
[
  {"newKey": "value1"},
  {"newKey": "value2"}
]
```

---

### 7. 配列の要素を削除する（特定の値を持つ要素を除外）

**Before:**

```json
[
  {
    "title": "task1",
    "status": "completed"
  },
  {
     "title": "task2",
     "status": "pending"
  },
  {
    "title": "task3",
    "status": "progress"
  }
]
```

**JSONata:**

```jsonata
payload[status != "completed"]
```

**After:**

```json
[
  {
    "title": "task2",
    "status":"pending"
  },
  {
    "title":"task3",
    "status":"progress"
  }
]
```

---

### 8. 数値の集計（合計）

**Before:**

```json
[
  { "price": 100 },
  { "price": 200 },
  { "price": 150 }
]
```

**JSONata:**

```jsonata
$sum(payload.price)
```

**After:**

```json
450
```

---

### 9. デフォルト値を適用する（値が存在しない場合）

**Before:**

```json
[
  { 
    "name": "Joe", 
    "age": null 
  },
  { 
    "name": "Charlie", 
    "age": 22 
  },
  { 
    "name": "Diana", 
    "age": 28 
  }
]
```

**JSONata:**

```jsonata
payload.{ "name": name, "age": age ? age : 18 }
```

**After:**

```json
[
  { 
    "name": "Joe", 
    "age": 18 
  },
  { 
    "name": "Charlie", 
    "age": 22 
  },
  { 
    "name": "Diana", 
    "age": 28 
  }
]
```

---

### 10. オブジェクトから特定のキーを削除する

**Before:**

```json
{
  "user": {
    "id": 12345,
    "name": "Helen",
    "password": "secret"
  }
}
```

**JSONata:**

```jsonata
{
  "id": payload.user.id,
  "name": payload.user.name
}
```

**After:**

```json
{
  "id": 12345,
  "name": "Helen"
}
```

---

### 11. 配列の長さを取得する

**Before:**

```json
[
  { "name": "Joe", "age": 18 },
  { "name": "Charlie", "age": 22 },
  { "name": "Diana", "age": 28 }
]
```

**JSONata:**

```jsonata
$count(payload)
```

**After:**

```json
3
```

---

### 12. 配列の特定の範囲を取得する

**Before:**

```json
[
  { "name": "Joe", "age": 18 },
  { "name": "Charlie", "age": 22 },
  { "name": "Diana", "age": 28 },
  { "name": "Heima", "age": 38 }
]
```

**JSONata:**

```jsonata
payload[[1..3]]
```

**After:**

```json
[
  {
    "name": "Charlie",
    "age": 22
  },
  {
    "name": "Diana",
    "age": 28
  },
  {
    "name": "Heima",
    "age": 38
  }
]
```

---

### 13. 配列の要素をソートする

**Before:**

```json
[
  { "name": "Joe", "age": 18 },
  { "name": "Charlie", "age": 22 },
  { "name": "Diana", "age": 28 }
]
```

**JSONata:**

```jsonata
payload^(-age)
```

**After:**

```json
[
  {
    "name": "Diana",
    "age": 28
  },
  {
    "name": "Charlie",
    "age": 22
  },
  {
    "name": "Joe",
    "age": 18
  }
]
```

---

### 14. 条件に基づいた値の変換

**Before:**

```json
[
  { "name": "Joe", "age": 18 },
  { "name": "Charlie", "age": 22 },
  { "name": "Diana", "age": 28 }
]
```

**JSONata:**

```jsonata
payload.{ "name": name, "category": age >= 21 ? "adult" : "minor" }
```

**After:**

```json
[
  { "name": "Joe", "category": "minor" },
  { "name": "Charlie", "category": "adult" },
  { "name": "Diana", "category": "adult" }
]
```

---

### 15. 重複する要素の削除

**Before:**

```json
[
  { "name": "Joe", "age": 18 },
  { "name": "Charlie", "age": 22 },
  { "name": "Joe", "age": 18 }
]
```

**JSONata:**

```jsonata
$distinct(payload)
```

**After:**

```json
[
  { "name": "Joe", "age": 18 },
  { "name": "Charlie", "age": 22 }
]
```

---

### 16. 部分一致によるフィルタリング

**Before:**

```json
[
  { "title": "Node-RED tutorial" },
  { "title": "JSONata guide" },
  { "title": "JavaScript basics" }
]
```

**JSONata:**

```jsonata
payload[title ~> /.*tutorial.*/]
```

**After:**

```json
[
  { "title": "Node-RED tutorial" }
]
```

---

### 17. 特定の値をキーとして新しいオブジェクトを作る

**Before:**

```json
[
  { 
    "name": "Joe", 
    "age": 18 
  },
  { 
    "name": "Charlie", 
    "age": 22 
  },
  { 
    "name": "Diana", 
    "age": 28 
  }
]
```

**JSONata:**

```jsonata
payload.{ $lookup("name"): $ }
```

**After:**

```json
[
  { 
    "Joe": {
      "name": "Joe", 
      "age": 18 
    }
  },
  {
    "Charlie": {
      "name": "Charlie", 
      "age": 22
    }
  }, 
  {
    "Diana": {
      "name": "Diana",
      "age": 28
    }
  }
]
```

---

### 18. 17の逆

**Before:**

```json
[
  { 
    "Joe": {
      "name": "Joe", 
      "age": 18 
    }
  },
  {
    "Charlie": {
      "name": "Charlie", 
      "age": 22
    }
  }, 
  {
    "Diana": {
      "name": "Diana",
      "age": 28
    }
  }
]
```

**JSONata:**

```jsonata
payload.*
```

**After:**

```json
[
  { 
    "name": "Joe", 
    "age": 18 
  },
  { 
    "name": "Charlie", 
    "age": 22 
  },
  { 
    "name": "Diana", 
    "age": 28 
  }
]
```

---

### 19. 17の逆で且つネストをフラットにする

**Before:**

```json
[
  {
    "Joe": {
      "name": "Joe",
      "details": {
        "age": 18,
        "city": "Texas City"
      }
    }
  },
  {
    "Charlie": {
      "name": "Charlie",
      "details": {
        "age": 22,
        "city": "San Francisco"
      }
    }
  },
  {
    "Diana": {
      "name": "Diana",
      "details": {
        "age": 28,
        "city": "New York"
      }
    }
  }
]
```

**JSONata:**

```jsonata
payload.{
  "name": $lookup($, $keys())[0].name,
  "age": $lookup($, $keys())[0].details.age,
  "city": $lookup($, $keys())[0].details.city
}
```

**After:**

```json
[
  {
    "name": "Joe",
    "age": 18,
    "city": "Texas City"
  },
  {
    "name": "Charlie",
    "age": 22,
    "city": "San Francisco"
  },
  {
    "name": "Diana",
    "age": 28,
    "city": "New York"
  }
]
```

---