用于检查地图上的某个键是否具有值的惯用方法

Dan*_*ero 13 clojure

检查地图上的某个键是否有值的惯用方法是什么?例如,如果我们有:

=> (def seq-of-maps [{:foo 1 :bar "hi"} {:foo 0 :bar "baz"}])
Run Code Online (Sandbox Code Playgroud)

要查找所有地图:foo == 0,我喜欢:

=> (filter (comp zero? :foo) seq-of-maps)
({:foo 0, :bar "baz"})
Run Code Online (Sandbox Code Playgroud)

但如果我想找到所有的地图:bar =="hi",我能想到的最好的是:

=> (filter #(= (:bar %) "hi") seq-of-maps)
({:foo 1, :bar "hi"})
Run Code Online (Sandbox Code Playgroud)

我发现它不太可读.这样做有更好/更惯用的方式吗?

Pep*_*ijn 13

惯用语是主观的,但我会这样做

=> (filter (comp #{"hi"} :bar) seq-of-maps)
Run Code Online (Sandbox Code Playgroud)

或者你做了什么.


mik*_*era 5

我个人喜欢重构这种事情来使用一个明确命名的高阶函数:

(def seq-of-maps [{:foo 1 :bar "hi"} {:foo 0 :bar "baz"}])

(defn has-value [key value]
  "Returns a predicate that tests whether a map contains a specific value"
  (fn [m]
    (= value (m key))))

(filter (has-value :bar "hi") seq-of-maps)
=> ({:foo 1, :bar "hi"})
Run Code Online (Sandbox Code Playgroud)

缺点是它为您提供了额外的功能定义来管理和维护,但我认为优雅/代码可读性是值得的.如果您多次重复使用谓词,从性能角度来看,这种方法也非常有效.