如何用jq从两个过滤后的数组元素提取数据生成单个输出对象
jq合并多分支数据查询解决方案
问题场景
输入JSON(已剔除无关字段)
{"modules": {"data": [{"id": "aod_play_area","data": [{"titles": {"primary": "Primary","secondary": "Secondary"}}]},{"id": "aod_tracks","data": [{"titles": {"primary": "First Artist name here","secondary": "First Track title here"},"uris": [{"id": "commercial-music-service-spotify","uri": "https://open.spotify.com/track/1234567890"},{"id": "commercial-music-service-apple","uri": "https://music.apple.com/gb/album/xyz/1234?i=9876"}]},{"titles": {"primary": "Second Artist name here","secondary": "Second Track title here"},"uris": [{"id": "commercial-music-service-spotify","label": "Spotify","uri": "https://open.spotify.com/track/555555555555"},{"id": "commercial-music-service-apple","label": "Apple Music","uri": "https://music.apple.com/gb/album/abc/5555?i=5555"}]}]}]}}
期望输出
{"title": "Primary - Secondary","tracks": [{"title": "First Track title","artist": "First Artist name","start": 3645,"end": 3820,"apple": "https://music.apple.com/gb/album/xyz/1234?i=9876","spotify": "https://open.spotify.com/track/1234567890"},{"title": "Second Track title","artist": "Second Artist name","start": 3645,"end": 3820,"apple": "https://music.apple.com/gb/album/abc/5555?i=5555","spotify": "https://open.spotify.com/track/555555555555"}]}
遇到的问题
单独编写jq查询可以提取标题或曲目数据,但合并查询时无输出,推测是第一个select进入数据分支后,第二个select无法找到目标数据。
解决方案
核心思路是先把modules.data数组转换为以id为键的对象,这样可以同时访问两个分支的数据,再构造最终输出:
.modules.data | from_entries | { title: (.aod_play_area.data[0].titles.primary + " - " + .aod_play_area.data[0].titles.secondary), tracks: .aod_tracks.data | map({ title: .titles.secondary, artist: .titles.primary, start: 3645, end: 3820, spotify: (.uris[] | select(.id == "commercial-music-service-spotify").uri), apple: (.uris[] | select(.id == "commercial-music-service-apple").uri) }) }
代码解释
.modules.data | from_entries:将原数组中每个元素的id作为键,元素本身作为值,转换成一个便于直接按id访问的对象,避免分支跳转后丢失数据。- 构造
title字段:从aod_play_area分支中取出primary和secondary标题,拼接成Primary - Secondary格式。 - 构造
tracks数组:遍历aod_tracks.data中的每个曲目:- 从
titles中提取title(secondary字段)和artist(primary字段); - 按期望输出硬编码
start和end值; - 从
uris数组中筛选出对应平台的链接,分别赋值给spotify和apple字段。
- 从
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

