12

我是一个新的clojure程序员。

鉴于...

{:foo "bar"}

有没有办法用值“bar”检索键的名称?

我查看了地图文档,可以看到一种检索键和值或仅检索值但不仅仅是键的方法。帮助表示赞赏!

4

3 回答 3

29

可以有多个键/值对,其值为“bar”。与它们的键相反,这些值不会被散列以进行查找。根据您想要实现的目标,您可以使用线性算法查找密钥,例如:

(def hm {:foo "bar"})
(keep #(when (= (val %) "bar")
          (key %)) hm)

或者

(filter (comp #{"bar"} hm) (keys hm))

或者

(reduce-kv (fn [acc k v]
             (if (= v "bar")
               (conj acc k)
               acc))
           #{} hm)

这将返回一系列键。如果您知道您的 val 彼此不同,您还可以创建一个反向查找哈希映射

(clojure.set/map-invert hm)
于 2013-08-11T20:46:09.330 回答
6
user> (->> {:a "bar" :b "foo" :c "bar" :d "baz"} ; initial map
           (group-by val)   ; sorted into a new map based on value of each key
           (#(get % "bar")) ; extract the entries that had value "bar"
           (map key))     ; get the keys that had value bar
(:a :c)
于 2013-08-11T22:18:53.270 回答
2

与许多其他情况一样,您可以用于:

(def hm {:foo "bar"})
(for [[k v] hm :when (= v "bar")] k)

并且使用“some”,您可以返回第一个匹配项而不是列表(可能是原始问题所暗示的):

(some (fn [[k v]] (if (= v "bar") k)) hm)
于 2020-06-08T10:50:26.517 回答