jqで↓これを
[
{
"role": "A",
"members": ["taro", "hanako"]
},
{
"role": "B",
"members": ["jiro"]
},
{
"role": "C",
"members": ["hanako", "jiro"]
}
]
↓こうしたい
[
{
"member": "taro",
"role": ["A"]
},
{
"member": "jiro",
"role": ["B", "C"]
},
{
"member": "hanako",
"role": ["A","C"]
},
]
二次元配列の転置ですかね。
行列の入れ替え。
やりかた
jq 'map({"role": .role, "member": .members[]}) | group_by(.member) | map({"member": .[0].member, "role": map(.role)})'
解説
参考
いきなり理解するのは苦しいので、ひとつずつ解説。
元データ
再掲
[
{
"role": "A",
"members": ["taro", "hanako"]
},
{
"role": "B",
"members": ["jiro"]
},
{
"role": "C",
"members": ["hanako", "jiro"]
}
]
map({"role": .role, "member": .members[]})
まずは、配列を展開して下記の形に変換します。
[
{
"role": "A",
"member": "taro"
},
{
"role": "A",
"member": "hanako"
},
{
"role": "B",
"member": "jiro"
},
{
"role": "C",
"member": "hanako"
},
{
"role": "C",
"member": "jiro"
}
]
こちらの記事にもお世話になりました。
書き方違いますが、参考にどうぞ。
group_by(.member)
members毎に集め直します。
[
[
{
"role": "A",
"member": "hanako"
},
{
"role": "C",
"member": "hanako"
}
],
[
{
"role": "B",
"member": "jiro"
},
{
"role": "C",
"member": "jiro"
}
],
[
{
"role": "A",
"member": "taro"
}
]
]
map({"member": .[0].member, "role": map(.role)})
最後がややこしいですね。
↓これを
[
{
"role": "A",
"member": "hanako"
},
{
"role": "C",
"member": "hanako"
}
]
↓これに変換する事を考えてみます。
{
"member": "hanako",
"role": [
"A",
"C"
]
}
入力された各要素を使って目的のオブジェクトを組み立てます。
"member": .[0].member
一つ前の手順で group_by() しているので、.member
は全部同じはずです。
なので、1つ目の member
の値を採用します。
"role": map(.role)
map関数を使って、各要素を集めて配列にまとめます。
map({ })
集めた各要素をオブジェクトとして出力します。
map関数なので、配列で出力されます。
参考
完成
全部まとめると、行列が入れ替わりました。
[
{
"member": "hanako",
"role": [
"A",
"C"
]
},
{
"member": "jiro",
"role": [
"B",
"C"
]
},
{
"member": "taro",
"role": [
"A"
]
}
]
備考
記事を書くために jqplay.org 使ってみました。
便利ですね。