我是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?
函数?
答案 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