我已经哈希地图Clojure中:扭转哈希映射Clojure中
{"key1" "value1"} {"key2" "value2"} {"key3" "value1"}
,我需要将其转换成
{"value1" {"key1" "key3"}} {"value2" {"key2"}}
哈希表这样做的任何Clojure的方式吗?
clojure.set/map-invert不会像覆盖重复值一样工作。
我已经哈希地图Clojure中:扭转哈希映射Clojure中
{"key1" "value1"} {"key2" "value2"} {"key3" "value1"}
,我需要将其转换成
{"value1" {"key1" "key3"}} {"value2" {"key2"}}
哈希表这样做的任何Clojure的方式吗?
clojure.set/map-invert不会像覆盖重复值一样工作。
(def m {"key1" "value1" "key2" "value2" "key3" "value1"})
(let [g (group-by val m)
vals (map #(map first %) (vals g))]
(zipmap (keys g) vals))
;;=> {"value2" ("key2"), "value1" ("key1" "key3")}
请尝试以下操作,我没有REPL来测试,它可能与原始答案略有不同,但是,您可以使用它来获取所需内容。
(group-by #(val (first %)) {"key1" "value1"} {"key2" "value2"} {"key3" "value1"})
你的问题很混乱。首先你说过你有散列图,你实际拥有的例子是许多散列图,或者如果你真的是一个散列图,那么你的例子是不正确的,因为它应该是{"key1" "value1" "key2" "value2" "key3" "value1"}
。其次,需要的输出是奇怪的,因为哈希映射中的值表示为映射本身,但最后一个值仅仅是散列映射中的单个值,这显然是不可能的,所以我想你的意思是值设置(不是地图)作为 {"value1" #{"key1" "key3"}} {"value2" #{"key2"}}
基于这些假设,一个可能的解决办法是:
(->> {"key1" "value1" "key2" "value2" "key3" "value1"}
(group-by second)
(map #(-> [(%1 0) (into #{} (map first (%1 1)))]))
(into {}))
这里的另一种选择:
(def maps [{"key1" "value1"} {"key2" "value2"} {"key3" "value1"}])
(into {}
(for [[k v] (group-by #(val (first %)) maps)]
[k (apply concat (map keys v))]))
;=> {"value1" ("key1" "key3"), "value2" ("key2")}
试试这个:
(def m {"key1" "value1" "key2" "value2" "key3" "value1"})
(reduce (fn [a x] (assoc a (second x) (conj (a (second x)) (first x)))) {} m)
=> {"value2" ("key2"), "value1" ("key3" "key1")}
注意,(可能)重复的值在列表中结束。或者,如由@ A.Webb评价建议的,上面可以简明地写成这样:
(reduce (fn [a [k v]] (update-in a [v] conj k)) {} m)
=> {"value2" ("key2"), "value1" ("key3" "key1")}
变异:'(减少(FN并[c [KV]](更新在C [V]缀k)){} m)' – 2013-03-16 19:49:10
@ A.Webb太棒了!我会用你的建议更新我的答案 – 2013-03-16 19:57:17