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

如何在jq中对数组不同部分应用不同函数/映射?

GPS定位JSON数据的jq批量处理问题

需求与现有实现

给定手机GPS定位JSON数据:

{
  "latitude": 66.32418638,
  "longitude": -121.77029769,
  "altitude": 465.46502685546875,
  "accuracy": 17.6742248535156,
  "vertical_accuracy": 36.48805236816406,
  "bearing": 0.0,
  "speed": 0.0,
  "elapsedMs": 55,
  "provider": "gps"
}

需要完成以下处理:

  • 提取latitude、longitude、altitude、accuracy、provider字段
  • 对latitude、longitude保留5位小数
  • 对altitude、accuracy取整
  • provider保持原样

目前已拆分实现三个独立的jq过滤器:

jq -j '[.latitude,.longitude]|map(.*100000|round/100000)' in.json
jq -j '[.altitude,.accuracy]|map(.|round)' in.json
jq -j '.provider' in.json

问题与解答

Q1:能否将这些过滤器合并为单个?

可以合并,两种简洁实现方式:

方式1:按字段分组处理

直接针对不同字段应用对应规则后组合成结果:

jq -j '[
  (.latitude, .longitude) | (.*100000 | round / 100000),
  (.altitude, .accuracy) | round,
  .provider
]' in.json

方式2:统一数组+索引判断

先构造包含所有目标数值字段的数组,结合索引判断应用规则,再追加provider:

jq -j '
  [.latitude, .longitude, .altitude, .accuracy] 
  | map( with_index as $idx | if $idx < 2 then .*100000|round/100000 else round end )
  + [.provider]
' in.json

Q2:处理大型数组时,能否按索引范围应用不同函数(无需指定属性名)?

完全可以。只要先把待处理元素整理成数组,利用with_index获取元素的索引位置,再通过分支判断对不同索引范围应用对应函数即可。

比如针对大型数组data_array,实现:

  • 索引0-1的元素保留5位小数
  • 索引2-3的元素取整
  • 索引4及以后的元素做自定义处理

代码示例:

jq '
  $data_array | map(
    with_index as $idx |
    if $idx < 2 then .*100000|round/100000
    elif $idx < 4 then round
    else . * 2  # 自定义其他处理逻辑
    end
  )'

Q3:是否需构建带分支判断的全局map()函数,按索引范围返回对应处理结果?

不需要专门构建全局map函数。jq原生的map配合with_index已经能直接实现按索引分支处理的逻辑,直接在map内部写判断代码即可,简洁直观。

如果需要复用相同的索引处理逻辑,可以封装成自定义函数(可选优化):

jq '
  def process_by_index:
    map(
      with_index as $idx |
      if $idx < 2 then .*100000|round/100000
      elif $idx < 4 then round
      else .
      end
    );
  # 调用示例
  [.latitude, .longitude, .altitude, .accuracy] | process_by_index + [.provider]
' in.json

错误代码修正

你之前的代码错误在于误用了index函数——index是用来查找元素在数组中的位置,而非获取当前元素的迭代索引。正确写法应该用with_index绑定当前元素的索引变量:

jq -j '[.latitude,.longitude,.altitude,.accuracy] | map( with_index as $idx | if $idx < 2 then .*100000|round/100000 else round end )' in.json

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 15:14:59