jq 通过仅使用数组中对象的某些值选择列表来转换数组

jq 通过仅使用数组中对象的某些值选择列表来转换数组

我有以下对象

{
  "name": "Papanito",
  "fields": [
    {
      "name": "Name1",
      "value": "Value1",
      "type": 0,
      "linkedId": null
    },
    {
      "name": "Name2",
      "value": "Value2",
      "type": 0,
      "linkedId": null
    },
    {
      "name": "Name3",
      "value": "Value3",
      "type": 0,
      "linkedId": null
    },
    {
      "name": "Name4",
      "value": "Value3",
      "type": 0,
      "linkedId": null
    }
  ],
}

我想在此转换

{
  "name": "Papanito",
  "fields": [
    "Name1": "Value1",
    "Name2": "Value2",
    "Name3": "Value3",
    "Name4": "Value4",
  ],
}

我尝试了几件事,但我还不知道该怎么做。

答案1

jq '.fields |= ( map(.key = .name | del(.type,.linkedId,.name)) | from_entries )' file

这会更新fields数组。首先,对于每个元素(使用map()),使用键key中的值创建一个键name。然后从元素中删除typelinkedId和键。现在,我们在数组的每个元素中name留下了 akey和一个键,这正是需要将值作为键与值关联起来的地方。valuefieldsfrom_entrieskeyvalue

对问题中给出的数据进行测试(删除尾随逗号),这会生成以下 JSON:

{
  "name": "Papanito",
  "fields": {
    "Name1": "Value1",
    "Name2": "Value2",
    "Name3": "Value3",
    "Name4": "Value3"
  }
}

请注意,您的预期输出是无效的 JSON,因为数组不能有键。因此,fields上面输出中的值是一个对象,而不是数组。

如果您想保留fields为数组,您可以稍微重新安排操作:

jq '.fields |= map([.key = .name | del(.type,.linkedId,.name)] | from_entries)' file

对于给定的数据(如上所述进行更正),这将生成相当于以下文档的内容:

{
   "name": "Papanito",
   "fields": [
      { "Name1": "Value1" },
      { "Name2": "Value2" },
      { "Name3": "Value3" },
      { "Name4": "Value3" }
   ]
}

这样做的好处是,具有相同原始name值的两个元素不会在结果中相互覆盖。


从概念上讲,上述删除我们不再需要的数据。以下变体提炼我们想要的数据。

这会生成上面的最后结果:

jq '.fields |= map({ (.name): .value })' file

我们可以fields通过合并列表中的条目来获得第一个结果(作为单个对象):

jq '.fields |= (map({ (.name): .value }) | add)' file

相关内容