我在clojure中有哈希图:
{"key1" "value1"} {"key2" "value2"} {"key3" "value1"}
我需要将其转换为
{"value1" {"key1" "key3"}} {"value2" {"key2"}}
任何clojure方法可以做到这一点?
clojure.set/map-invert 不会像覆盖重复值一样工作。
我在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")}
试试这个:
(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")}
尝试以下,我没有 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")}