初始files.json
文档状态:
[
{
"filename": "a",
"dir": "foo",
"type": "unknown"
},
{
"filename": "b",
"dir": "foo",
"type": "unknown"
},
{
"filename": "c",
"dir": "bar",
"type": "unknown"
},
{
"filename": "a",
"dir": "bar",
"type": "unknown"
}
]
当"filename“值在文档中只出现一次时,"type”值将只依赖于"dir“值:"dir" == "foo" --> "type" = 0
和"dir" == "bar" --> "type" = 1
当"filename“值同时存在于"foo”和"bar“目录中时,”==“的值必须为2,如下所示:
[
{
"filename": "a",
"dir": "foo",
"type": "2"
},
{
"filename": "b",
"dir": "foo",
"type": "0"
},
{
"filename": "c",
"dir": "bar",
"type": "1"
},
{
"filename": "a",
"dir": "bar",
"type": "2"
}
]
"dir“值将始终限制为"foo”或"bar“值的两个可能替代值,并且永远不会为空。
即使是"filename“值也会被设置,因为这些都是真正的文件,所以在文档中最多只能出现两次。
我想在Linux的Bash脚本中运行jq 1.5 (2015年8月16日稳定版)来实现这一点。
发布于 2018-08-05 11:20:05
这是一个类似@CharlesDuffy的解决方案,但更简短,更具"jq-ish":
(reduce .[] as $x ({}; .[$x.filename] += [$x.dir])
| map_values(unique)) as $dirs
| map( $dirs[.filename] as $d
| .type |= if $d|length > 1 then 2
elif $d[0] == "bar" then 1
else 0
end)
使用catalog/3
在通用助手函数catalog/3
的帮助下
def catalog(s; keyp; valuep):
reduce s as $x ({}; (.[$x|keyp|tostring]) += [$x|valuep]);
解决方案变得更具可读性:
(catalog(.[]; .filename; .dir) | map_values(unique)) as $dirs
| map( $dirs[.filename] as $d
| .type |= if $d|length > 1 then 2
elif $d[0] == "bar" then 1
else 0
end)
发布于 2018-08-05 00:58:36
一种方法是使用group_by
。在下面的示例中,group_by
使用得很简单,因此数组中最终结果的排序由.filename决定;如果排序不令人满意,可以使用相同的技术构造一个查找表,然后对原始数组使用该表。
[group_by(.filename)[]
| (map(.dir)
| unique
| if length>1 then length
elif .[0] == "foo" then 0
elif .[0] == "bar" then 1
else .[0] # just in case
end) as $type
| (.[] + {type: $type} ) ]
输出
[
{
"filename": "a",
"dir": "foo",
"type": 2
},
{
"filename": "a",
"dir": "bar",
"type": 2
},
{
"filename": "b",
"dir": "foo",
"type": 0
},
{
"filename": "c",
"dir": "bar",
"type": 1
}
]
https://stackoverflow.com/questions/51684565
复制相似问题