Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 如何将命名列表转换为对象数组_Arrays_Json_Iteration_Jq - Fatal编程技术网

Arrays 如何将命名列表转换为对象数组

Arrays 如何将命名列表转换为对象数组,arrays,json,iteration,jq,Arrays,Json,Iteration,Jq,我有一些数据看起来像这样 { "type1": [ "a", "b" ], "type2": [ "c", "d" ], "type3": "x" } 我想把它转换成 [ {"value": "a", "type": "type1" }, {"value": "b", "type": "type1" }, {"value": "c", "type": "type2" }, {"value": "d"

我有一些数据看起来像这样

{
    "type1": [
      "a", "b"
    ],
    "type2": [
      "c", "d"
    ],
    "type3": "x"
}
我想把它转换成

[
    {"value": "a", "type": "type1" },
    {"value": "b", "type": "type1" },
    {"value": "c", "type": "type2" },
    {"value": "d", "type": "type2" },
    {"value": "x", "type": "type3" },
]
数组元素可以有一个或多个值。使用jq是否可能做到这一点

我能够处理非数组元素,但我的表达式只保留列表中的最后一项

to_entries 
  | map_values({value:[.value]|flatten, type:.key})
  | map_values({value:.value[], type:.type})
我得到这个结果,其中元素“b”和“d”被排除在结果之外

[
  {
    "value": "a",
    "type": "type1"
  },
  {
    "value": "c",
    "type": "type2"
  },
  {
    "value": "x",
    "type": "type3"
  }
]

我能够用以下方法解决这个问题

  • 将项转换为键值对
  • 将值转换为数组并展平
  • 映射每个项目
    • 在变量中存储类型
    • 映射数组中的每个值,添加type属性
    • 展平嵌套数组

我将您的数据放在d.json中,并将其放在d.jq中:

# vim: tabstop=2 expandtab shiftwidth=2 softtabstop=2
[ 
  .
  |to_entries[]
  |.key as $k
  |(
    (.value|strings|{"type":($k),"value":.}),
    (.value|arrays|reduce .[] as $i ( [];  . += [ { "type": ($k), "value":  $i } ] ) )[]
  )
]
然后与jq一起运行

jq -f d.jq d.json
我知道一定有更好的办法:-) 但你最终会:

[
  {
    "type": "type1",
    "value": "a"
  },
  {
    "type": "type1",
    "value": "b"
  },
  {
    "type": "type2",
    "value": "c"
  },
  {
    "type": "type2",
    "value": "d"
  },
  {
    "type": "type3",
    "value": "x"
  }
]

以下是一个高效、简洁且可能是“规范”的解决方案:

[to_entries[]
 | (if .value|type == "array" then {value: .value[]} else {value} end)
   + {type: .key} ]
或者,如果您更喜欢使用
映射
,则可以使用等效方法:

to_entries
| map( (if .value|type == "array" then {value: .value[]} 
        else {value}
        end)
      + {type: .key} )

这里的微妙之处在于,
{value:.value[]}
扩展为JSON对象流,就像:
.value[]{value:.}

我更喜欢交替使用各种类型的过滤器,使其更紧凑。假设您只需要处理数组或标量的值,我会这样写:

[to_entries[]|{value:(.value | arrays[]/]),类型:.key}]


不要低估可以生成多个值的表达式的有用性,它可以使过滤器在有效使用时变得不那么复杂。

jq“$(cat d.jq)”d.json
应更改为
jq-f d.jq d.json
。谢谢。如果我删除
|字符串
,它也适用于对象。谢谢,我知道即使值是对象,这也能起作用。是的,这就是jq通用性的要点,没有复杂性!哇!短而整洁。
to_entries
| map( (if .value|type == "array" then {value: .value[]} 
        else {value}
        end)
      + {type: .key} )