查找地图是否包含多个键

时间:2015-01-13 02:24:59

标签: clojure clojurescript

我是Clojure的新手,我想知道是否有办法测试地图是否有多个键。我注意到contains?只检查一个密钥

我想做的事情:

(def mario 
    {:position {:x 1 :y 2}
     :velocity {:x 2 :y 0}
     :mass 20})

;;Test if mario has a position and a velocity
(contains-many? mario :position :velocity) ;;true

;;Test if mario has a mass and a jump-height
(contains-many? mario :mass :jump-height) ;;false

基本上,clojure库中是否有像contains-many?这样的函数,如果没有,你会如何实现contains-many?函数?

4 个答案:

答案 0 :(得分:17)

显示了正确的答案,但我想指出另一个优雅的解决方案,它可以提供有关地图值的知识。如果您确定他们是真实的(即{not nil而不是false):

(every? m ks)

这是因为map是(一元)函数,它们将相应的值返回给参数。但请注意({:x nil} :x) => nil

答案 1 :(得分:7)

我不知道有任何功能。还需要定义是否希望地图包含每个键或仅某些键。我选择了每个案例,如果您想要某些版本,只需将every?替换为some?

我的直接,未优化的版本是:

(defn contains-many? [m & ks]
  (every? #(contains? m %) ks))

已通过测试:

(deftest a-test
  (testing "Basic test cases"
    (let [m {:a 1 :b 1 :c 2}]
      (is (contains-many? m :a))
      (is (contains-many? m :a :b))
      (is (contains-many? m :a :b :c))
      (is (not (contains-many? m :a :d)))
      (is (not (contains-many? m :a :b :d))))))

编辑:使用noisesmith的建议简化

答案 2 :(得分:1)

以下是另一种使用clojure.set的解决方案,该解决方案适用于非真实值:

(require '[clojure.set :as set])

(defn contains-many? [m & ks]
  (empty? (set/difference (set ks) (set (keys m)))))

答案 3 :(得分:0)

您可以利用clojure.set/subset?

phi