0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JSONataでオブジェクトをフラット化する方法

Posted at

はじめに

JSONata を使って JSON の階層化されたオブジェクトをフラット化する方法についていろいろ模索してみたためその結果をまとめる。

きっかけは、AWS Step Functions でステート間のデータ変換で JSONata が使えるようになり 1、早速使ってみたところJSONをフラット化したい場面が出てきて本記事のトピックについて考えることになったことだ。同じ問題に直面した人の参考になれば幸いである。

環境

以下のバージョンで動作確認済み。

  • JSONata 2.0.6

動作確認は JSONata Exerciser を利用。

クエリ対象のJSON

今回扱うJSONのサンプル。

{
  "target": {
    "a": 0,
    "b": {
      "b1": 1,
      "b2": 2,
      "b3": 3
    },
    "c": {
      "c1": 4,
      "c2": 5
    },
    "d": 6,
    "e": 7
  }
}

クエリ結果として求めるもの

上記のJSONを以下のように変換したいものとする。

{
  "a": 0,
  "b1": 1,
  "b2": 2,
  "b3": 3,
  "c1": 4,
  "c2": 5,
  "d": 6,
  "e": 7
}

クエリ

その1: 泥臭いやり方

. 演算子を使って欲しい項目を取って所望にキーに割り当てるだけ。
項目が少ないならいいが、多かったり動的に項目数が変わったりする場合は厳しい。

{
  "a": target.a,
  "b1": target.b.b1,
  "b2": target.b.b2,
  "b3": target.b.b3,
  "c1": target.c.c1,
  "c2": target.c.c2,
  "d": target.d,
  "e": target.e
}

その2: 組込関数を使って少し楽をするやり方

組込関数 $merge(array<object>) を利用して、 target.b, target.c の中身を一々書かなくて済む。
元々フラットな階層にあった target.a などはオブジェクトとして用意してあげる必要があるのが難点。
親階層の項目が少なく、フラット化したい子階層の項目が多い場合にはこれでも十分と思われる。

$merge([
  {"a": target.a},
  target.b,
  target.c,
  {"d": target.d, "e": target.e}
])

その3: よりシンプルに組込関数を活用するやり方

その2で $merge([...]) の中に入れた各要素を $map で動的に作るやり方。
親階層にも項目が多い場合にも耐えられる。

$merge([
  $map($keys(target), function($k) {
    $k in ["b", "c"] ? $lookup(target, $k) : {$k: $lookup(target, $k)}
  })
])

クエリ分解・解説

1. $keys(target)
  • target オブジェクトのキー(["a", "b", "c", "d", "e"])を配列として取得
2. $map(array, function)
  • $map は配列の各要素に function 2 を適用し、その結果の配列を返すもの
  • ここでは $keys(target) で得た各キー $k に対して処理を行う
3. function($k) { ... }
  • 中身は三項演算子 (条件式 ? 真の場合の値 : 偽の場合の値) を使っている
  • $k が "b" または "c" の場合は、target.btarget.c の中身(オブジェクト)をそのまま返す
  • それ以外のキーは、{$k: $lookup(target, $k)} で「キー: 値」の形のオブジェクトにして返す
4. $merge([...])
  • $map で作った配列を $merge で1つのオブジェクトにまとめる

ここで登場した $merge, $keys, $lookup について詳しくは公式ドキュメント 3 を参照されたい。

  1. https://aws.amazon.com/jp/blogs/news/simplifying-developer-experience-with-variables-and-jsonata-in-aws-step-functions/

  2. https://docs.jsonata.org/higher-order-functions#map

  3. https://docs.jsonata.org/object-functions

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?