【问题标题】:Clojure get map key by valueClojure 按值获取映射键
【发布时间】:2013-08-11 20:30:26
【问题描述】:

我是一名新的 clojure 程序员。

鉴于...

{:foo "bar"}

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

我查看了地图文档,可以看到一种检索键和值或仅检索值但不只是键的方法。感谢您的帮助!

【问题讨论】:

  • 当然,但这通常意味着你的数据结构是颠倒的。
  • 取决于你到底在做什么(也许你可以改变创建地图的代码,或者你需要两个方向),但我的直觉是:是的。

标签: clojure


【解决方案1】:

可以有多个值为“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)

【讨论】:

  • 如果 hm 类似于 {1 ["bar" "choco"]},你会如何做同样的事情?如果值列表是“bar”,那么想法是在第一个元素的位置获得 1?
  • @smaug 这从代码中应该很明显。也许我误解了你的问题?
【解决方案2】:
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)

【讨论】:

    【解决方案3】:

    在许多其他情况下,您可以用于:

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

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

    (some (fn [[k v]] (if (= v "bar") k)) hm)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-04
      • 1970-01-01
      • 2011-06-18
      • 1970-01-01
      • 2015-08-02
      • 2017-02-04
      • 1970-01-01
      相关资源
      最近更新 更多