每当键/值重复时,如何向 jq 数组添加新键

问题描述 投票:0回答:1

这是输入的 json。在此示例中,json 键/值...“foo:bar”不断随机重复。顺序并不重要,尽管它看起来是交替重复的。

[
  {
    "foo": "bar",
    "id": "baz"
  },
  {
    "thud": "grunt",
    "id": "fum"
  },
  {
    "foo": "bar",
    "id": "noot"
  },
  {
    "zot": "toto",
    "id": "pluto"
  },
  {
    "foo": "bar",
    "id": "toto"
  }  
]

每当某个键/值重复时,与其删除它,不如向该特定元素添加一个额外的键/值,如下所示 所需的输出将是:

[
  {
    "foo": "bar",
    "id": "baz"
  },
  {
    "thud": "grunt",
    "id": "fum"
  },
  {
    "foo": "bar",
    "id": "noot",
    "desc": "1st duplicate found
  },
  {
    "zot": "toto",
    "id": "pluto"
  },
  {
    "foo": "bar",
    "id": "toto",
    "desc": "2nd duplicate found"
  } 
]

再次强调,顺序和编号不相关/不需要。添加它仅用于表达目的

找到了几种删除重复项的解决方案,但无法在解决此问题方面取得任何进展

感谢上述任何提议的决议

非常感谢您的宝贵时间

尝试了复杂的解决方案,将 json 分成两部分,并与 -n 和 argjson 合并,没有太多突破

json duplicates jq key-value
1个回答
0
投票

这是一种使用

tostream
fromstream
通过流表示解构和重建输入的方法,流表示是包含路径及其相应值的数组流。
foreach
循环迭代此流,复制每个项目以供以后重建。此外,它还跟踪由路径的第一项减少的每个路径值对(匹配的发生与它们在原始输入数组中的位置无关),并使用计数器注册每个出现。如果大于 1,则还输出另一个项目(通过将
_dup
添加到最后一个路径项目来区分),并以当前计数作为值。

fromstream(
  foreach (tostream | [., (.[0] |= .[1:] | @json)]) as [$s,$j] (
    {};
    if $s | has(1) then .[$j] += 1 end;
    if .[$j] > 1 then [($s[0] | last += "_dup"), .[$j]] else empty end,
    $s
  )
)
[
  {
    "foo": "bar",
    "id": "baz"
  },
  {
    "thud": "grunt",
    "id": "fum"
  },
  {
    "foo_dup": 2,
    "foo": "bar",
    "id": "noot"
  },
  {
    "zot": "toto",
    "id": "pluto"
  },
  {
    "foo_dup": 3,
    "foo": "bar",
    "id": "toto"
  }
]

演示

© www.soinside.com 2019 - 2024. All rights reserved.