jq:将对象数组转换为对象
jq: translate array of objects to object
我收到 curl 的回复,格式如下:
[
{
"list": [
{
"value": 1,
"id": 12
},
{
"value": 15,
"id": 13
},
{
"value": -4,
"id": 14
}
]
},
...
]
给定这样的 ID 之间的映射:
{
"12": "newId1",
"13": "newId2",
"14": "newId3"
}
我想做这个:
[
{
"list": {
"newId1": 1,
"newId2": 15,
"newId3": -4,
}
},
...
]
这样我就得到了从 id 到值的映射(并且在这个过程中我想重新映射 id)。
我已经为此工作了一段时间,但每次都遇到死胡同。
注意:如有必要,我可以使用 Shell 等来执行循环。
编辑:这是我目前开发的一个版本:
jq '[].list.id = ($mapping.[] | select(.id == key)) | del(.id)' -M --argjson "mapping" "$mapping"
我不认为它是最好的,但我正在寻找是否可以找到更接近我需要的旧版本。
[编辑:以下回复是对问题的回答,它描述了 (a) 如下所示的映射,以及 (b) 具有以下形式的输入数据:
[
{
"list": [
{
"value": 1,
"id1": 12
},
{
"value": 15,
"id2": 13
},
{
"value": -4,
"id3": 14
}
]
}
]
编辑结束]
在下文中,我将假设映射可通过以下函数获得,但这是一个无关紧要的假设:
def mapping: {
"id1": "newId1",
"id2": "newId2",
"id3": "newId3"
} ;
以下 jq 过滤器将产生所需的输出:
map( .list
|= (map( to_entries[]
| (mapping[.key]) as $mapped
| select($mapped)
| {($mapped|tostring): .value} )
| add) )
给猫剥皮的方法有很多。我会这样做:
.[].list |= reduce .[] as $i ({};
($i.id|tostring) as $k
| (select($mapping | has($k))[$mapping[$k]] = $i.value) // .
)
您只需通过单独的文件或参数提供映射。
$ cat program.jq
.[].list |= reduce .[] as $i ({};
($i.id|tostring) as $k
| (select($mapping | has($k))[$mapping[$k]] = $i.value) // .
)
$ cat mapping.json
{
"12": "newId1",
"13": "newId2",
"14": "newId3"
}
$ jq --argfile mapping mapping.json -f program.jq input.json
[
{
"list": {
"newId1": 1,
"newId2": 15,
"newId3": -4
}
}
]
这是修改后的问题的无减少解决方案。
在下文中,我将假设映射可通过以下函数获得,但这是一个无关紧要的假设:
def mapping:
{
"12": "newId1",
"13": "newId2",
"14": "newId3"
} ;
map( .list
|= (map( mapping[.id|tostring] as $mapped
| select($mapped)
| {($mapped): .value} )
| add) )
"select" 是为了安全起见(即,它检查所考虑的 .id 是否确实已映射)。通过编写 {($mapped|tostring): .value}
.
来确保 $mapped
是一个字符串可能也是合适的
我收到 curl 的回复,格式如下:
[
{
"list": [
{
"value": 1,
"id": 12
},
{
"value": 15,
"id": 13
},
{
"value": -4,
"id": 14
}
]
},
...
]
给定这样的 ID 之间的映射:
{
"12": "newId1",
"13": "newId2",
"14": "newId3"
}
我想做这个:
[
{
"list": {
"newId1": 1,
"newId2": 15,
"newId3": -4,
}
},
...
]
这样我就得到了从 id 到值的映射(并且在这个过程中我想重新映射 id)。
我已经为此工作了一段时间,但每次都遇到死胡同。
注意:如有必要,我可以使用 Shell 等来执行循环。
编辑:这是我目前开发的一个版本:
jq '[].list.id = ($mapping.[] | select(.id == key)) | del(.id)' -M --argjson "mapping" "$mapping"
我不认为它是最好的,但我正在寻找是否可以找到更接近我需要的旧版本。
[编辑:以下回复是对问题的回答,它描述了 (a) 如下所示的映射,以及 (b) 具有以下形式的输入数据:
[
{
"list": [
{
"value": 1,
"id1": 12
},
{
"value": 15,
"id2": 13
},
{
"value": -4,
"id3": 14
}
]
}
]
编辑结束]
在下文中,我将假设映射可通过以下函数获得,但这是一个无关紧要的假设:
def mapping: {
"id1": "newId1",
"id2": "newId2",
"id3": "newId3"
} ;
以下 jq 过滤器将产生所需的输出:
map( .list
|= (map( to_entries[]
| (mapping[.key]) as $mapped
| select($mapped)
| {($mapped|tostring): .value} )
| add) )
给猫剥皮的方法有很多。我会这样做:
.[].list |= reduce .[] as $i ({};
($i.id|tostring) as $k
| (select($mapping | has($k))[$mapping[$k]] = $i.value) // .
)
您只需通过单独的文件或参数提供映射。
$ cat program.jq
.[].list |= reduce .[] as $i ({};
($i.id|tostring) as $k
| (select($mapping | has($k))[$mapping[$k]] = $i.value) // .
)
$ cat mapping.json
{
"12": "newId1",
"13": "newId2",
"14": "newId3"
}
$ jq --argfile mapping mapping.json -f program.jq input.json
[
{
"list": {
"newId1": 1,
"newId2": 15,
"newId3": -4
}
}
]
这是修改后的问题的无减少解决方案。
在下文中,我将假设映射可通过以下函数获得,但这是一个无关紧要的假设:
def mapping:
{
"12": "newId1",
"13": "newId2",
"14": "newId3"
} ;
map( .list
|= (map( mapping[.id|tostring] as $mapped
| select($mapped)
| {($mapped): .value} )
| add) )
"select" 是为了安全起见(即,它检查所考虑的 .id 是否确实已映射)。通过编写 {($mapped|tostring): .value}
.
$mapped
是一个字符串可能也是合适的