简体   繁体   English

在clojure中反转哈希映射

[英]reversing hash map in clojure

I've hash-map in clojure: 我在clojure中使用哈希映射:

{"key1" "value1"} {"key2" "value2"} {"key3" "value1"}

and i need to convert it into hash map of 我需要将其转换为哈希映射

{"value1" {"key1" "key3"}} {"value2" {"key2"}}

Any clojure way of doing this? 这样做的任何clojure方式?

clojure.set/map-invert will not work as if it overrides repeated values. 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")}

Give this a try: 尝试一下:

(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")}

Notice that the (possibly) repeated values end up in a list. 请注意,(可能)重复的值最终会出现在列表中。 Or, as suggested by @A.Webb in the comments, the above can be concisely written like this: 或者,正如@ 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"})

Your question is really confusing. 你的问题真的令人困惑。 First you said you have hash-map, what you actually have as example is many hash-maps or if you really mean a single hash-map then your example is incorrect as it should be {"key1" "value1" "key2" "value2" "key3" "value1"} . 首先你说你有哈希映射,你实际上有什么例子是很多哈希映射,或者如果你真的是一个哈希映射,那么你的例子是不正确的,因为它应该是{"key1" "value1" "key2" "value2" "key3" "value1"} Second, the required output is weird in the sense that the values in the hash-map are represented as maps themselves but the last value is just a single value in a hash-map which is obviously not possible, so I guess you mean the values are set (not map) as {"value1" #{"key1" "key3"}} {"value2" #{"key2"}} 其次,所需的输出很奇怪,哈希映射中的值表示为映射本身,但最后一个值只是哈希映射中的单个值,这显然是不可能的,所以我猜你的意思是值设置(不是地图)为{"value1" #{"key1" "key3"}} {"value2" #{"key2"}}

Based on all these assumptions one possible solution would be: 基于所有这些假设,一种可能的解决方案是:

(->> {"key1" "value1" "key2" "value2" "key3" "value1"}
     (group-by second)
     (map #(-> [(%1 0) (into #{} (map first (%1 1)))]))
     (into {}))

Here's another alternative: 这是另一种选择:

(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")}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM