如何使用jq反转映射并为重复值创建列表



假设我有一个JSON映射,如下所示:

{
"a": "1",
"b": "3",
"c": "2",
"d": "1"
}

如何反转它并为重复项创建列表。所以最后是这样的:

{
"1": [ "a", "d"],
"2": "c",
"3": "b" 
}

{
"1": [ "a", "d"],
"2": ["c"],
"3": ["b"] 
}

谢谢!!!

由于JSON对象作为数学函数有一个明显的解释,因此它有一个关系逆,正如问题中提到的第二种可能性所建议的那样,与具有数组值键的JSON对象非常相似。

不幸的是,由于JSON对象中的键都必须是JSON字符串,因此任何";逆";JSON对象到JSON对象的映射必须限制域,或者附带警告。

下面的定义避免了对域的限制,而是注意它实际上返回了map_values(tostring)的逆;也就是说,实际上,它将输入JSON对象的所有值都视为字符串。例如,它不区分{"k":1}和{"k&":"1"}。

inverseMapping

以下实现避免了group_by:带来的排序

# Input: a JSON object, $in, viewed as a mapping of keys to strings;
# Output: a JSON object, all values of which are arrays.
# The output represents the inverse relation defined
# by $in|map_values(tostring)
def inverseMapping: 
reduce to_entries[] as $pair ({};
.[$pair.value|tostring] += [$pair.key]);

示例:使用问题中的JSON数据,输出为:

{"1":["a","d"],"3":["b"],"2":["c"]}

quasiInverseMapping

以下函数实现了问题中提到的第一种可能性所设想的转换:

# Input: a JSON object, $in;
# Output: a JSON object, $out, representing the inverse relation
#         as above but such that:  
#         if ($in[$key]|tostring) is a distinct value, $v,
#         then $out[$v] == $key
def quasiInverseMapping:
reduce to_entries[] as $pair ({};
($pair.value|tostring) as $v
| if (.[$v]|type) == "array" then .[$v] += [$pair.key]
elif .[$v] then .[$v] = [.[$v], $pair.key]
else .[$v] = $pair.key
end) ;

示例:使用问题中的JSON数据,输出为:

{"1":["a","d"],"3":"b","2":"c"}

最新更新