由于 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"}