jq中能否嵌套select表达式?筛选特定元素遇空结果求解
动态获取日期筛选jq数组元素
输入数据:
{ "xs": [ { "id": "a", "ts": "2023-01-03" }, { "id": "b", "ts": "2023-01-01" }, { "id": "c", "ts": "2023-01-02" } ] }
需求:筛选出id为c的元素——将xs数组按ts字段排序后,它是第一个ts大于id为b的元素的ts的项。
硬编码日期的代码可以正常运行:
.xs | sort_by(.ts) | map(select(.ts > "2023-01-01")) | first
但尝试动态获取id为b的日期时,以下代码返回空列表:
.xs | sort_by(.ts) | map(select(.ts > select(.id == "b").ts)) | first
问题原因
内层的select(.id == "b")是在map遍历的单个数组元素上下文里执行的,每个元素单独判断是否id为b:
- 遍历到
a或c时,select(.id == "b")返回空,.ts为null,字符串与null的比较不成立; - 遍历到
b时,select(.id == "b")返回自身,但"2023-01-01" > "2023-01-01"不成立;
最终没有符合条件的元素,返回空列表。
解决方法
先把id为b的ts提取为变量,再用变量进行比较,两种常见可行写法:
写法一:用as绑定变量
.xs | (map(select(.id == "b").ts) | first) as $b_ts | sort_by(.ts) | map(select(.ts > $b_ts)) | first
写法二:先存储变量到当前对象
.b_ts = (.xs[] | select(.id == "b").ts) | .xs | sort_by(.ts) | map(select(.ts > .b_ts)) | first
两种写法都能正确返回目标元素:
{ "id": "c", "ts": "2023-01-02" }
内容的提问来源于stack exchange,提问作者wmli
相关产品推荐
相关产品推荐

