You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在jq函数中使用传入的键参数构造对象

问题描述

我经常需要在jq中创建可复用的函数,对输入的指定字段执行转换操作。比如尝试写过这两个函数:

示例函数1:仅保留指定字段

def keep_field_only(field):
  {field}
;

示例函数2:按指定字段统计数量

def count_by(field):
  group_by(field) |
  map(
    {
      field: .[0].field,
      count: length
    }
  )
;

问题在于:group_by(field)能正常使用传入的字段参数,但用这个参数构造对象(比如仅保留指定键、或者构造统计结果的键)时无法正常工作。

我知道可以用path/1解决,但会大幅增加代码复杂度;另一种方法是在函数开头复制字段成新键,结尾再删除,但既低效又不易读。想找更简洁、可读性更强的实现方式。

更新内容

  • 示例输入:
[
  {"type":1, "name": "foo"},
  {"type":1, "name": "bar"},
  {"type":2, "name": "joe"}
]
  • 期望调用及结果:
    调用.[ ] | keep_field_only(.type),输出:
{"type": 1}
{"type": 1}
{"type": 2}

调用count_by(.type),输出:

[
  {"type":1, "count": 2},
  {"type":2, "count": 1}
]

解决方案

在jq中,实现动态键名的对象构造,核心是利用[(key)]: value语法——把动态的键用括号包裹,jq就会将其解析为键名而非字符串字面量,这是最简洁直观的解决方式。

改进后的keep_field_only函数

def keep_field_only(field):
  { (field): .[field] }
;

这里(field)会被解析为传入的字段名(比如.type对应的"type"),再取当前对象中该字段的值,最终构造出仅包含目标键值对的对象。

改进后的count_by函数

def count_by(field):
  group_by(field) |
  map(
    {
      (field): .[0][field],
      count: length
    }
  )
;

同样用(field)作为动态键名,. [0][field]取分组后第一个元素的对应字段值(分组内所有元素的该字段值一致),结合length统计分组长度,生成符合预期的统计结果。

验证调用

用示例输入测试:

  1. 保留指定字段:
jq '.[ ] | keep_field_only(.type)' input.json

输出与预期完全一致。

  1. 按字段统计:
jq 'count_by(.type)' input.json

输出符合预期。

这种方式无需额外的字段复制或path操作,代码简洁直观,可读性强。

内容的提问来源于stack exchange,提问作者wass rubleff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 01:05:17