json - 使用 JQ 扩展对 JSON 中同级值的引用

标签 json jq nested-loops lookup

我有一个 JSON 文档,其中包含宏配置。我需要扩展引用其他元素的宏。为简单起见,请考虑此输入文档。

[
  {
    "first": "Tim",
    "Full": "{first} {last}",
    "last": "Smith"
  },
  {
    "first": "Jane",
    "Full": "{first} {last}",
    "last": "Doe"
  }
]

性能在这里并不是最重要的,所以我不介意盲目地检查每个其他元素中出现的每个元素。

我制定了以下逻辑作为概念证明。但无法弄清楚如何在 $lookup 上添加嵌套循环更新其他with_entries值。

jq  '
  .[]
| . as $lookup
| with_entries(
    .value=(
      .value
      | sub("{first}"; $lookup.first)
    )
  )
'

JQ 处理值/文档流,感觉我现在需要使用两个流。我希望通过使用 $lookup 来实现这一点供后面引用。现在我被困住了。

解决方案 oguz ismail 为原始问题(请给他们+1)提供了一个很好的解决方案,该解决方案使用了map_values()。说得很清楚了,我想把它放在这里以供引用。您会注意到它使用命名组 (?<found_key>.*?)在正则表达式中(参见 oniguruma 的 named group )

map(. as $lookup | map_values(gsub("\\{(?<found_key>.*?)\\}"; $lookup[.found_key])))

我问结构体中有非字符串元素时如何处理。下面是一个包含颜色数组的示例:

[
  {
    "first": "Tim",
    "Full": "{first} {last}",
    "last": "Smith",
    "colors": ["red", "blue"]
  }
]

oguz ismail 也为这种结构提供了一个解决方案,它只尝试修改字符串元素:

map(
  . as $lookup
  | (.[] | strings)
  |= gsub("\\{(?<found_key>.*?)\\}"; $lookup[.found_key])
)

最佳答案

您可以将 gsub 与命名捕获组一起使用,以便在一次运行中扩展所有宏,而无需对其名称进行硬编码。而且,with_entries 在这种情况下根本没有帮助;请改用 map_values

map(. as $lookup | map_values(gsub("\\{(?<found_key>.*?)\\}"; $lookup[.found_key])))

Online demo

关于json - 使用 JQ 扩展对 JSON 中同级值的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66104360/

相关文章:

jq - 用范围替换数组中的连续整数

json - 如何判断 jq 过滤器是否成功从 JSON 数据结构中提取数据?

Python、嵌套循环、匹配和性能

ios - 如何在ios7中解析此json数据

python - 解析 JSON 以查找键的值

json - jq 如何获取所有值并用于脚本参数

java - 计算文件中多组 int 值

java - 使用两个嵌套的 for 循环和一个构造函数打印出重复模式

ruby-on-rails - 如何隐藏json文件的分页

php - jqGrid 在插入和更新后奇怪地重新加载数据