查找地图是否包含多个键
Find if a map contains multiple keys
我是 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?
函数?
我不知道有任何功能可以做到这一点。还需要定义您希望地图包含 every 键还是只包含 some 键。我选择了 every 案例,如果你想要 some 版本,只需将 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 的建议进行了简化
已显示正确答案,但我想指出另一个优雅的解决方案,该解决方案假定了解地图值。当您确定它们是真实的时(即:不是 nil
也不是 false
):
(every? m ks)
这是因为映射是(一元)函数,return 参数对应的值。但请注意 ({:x nil} :x) => nil
.
这是另一个使用 clojure.set
的解决方案,适用于非真实值:
(require '[clojure.set :as set])
(defn contains-many? [m & ks]
(empty? (set/difference (set ks) (set (keys m)))))
您可以利用 clojure.set/subset?
(clojure.set/subset?
#{:position :velocity}
(set (keys mario)))
我是 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?
函数?
我不知道有任何功能可以做到这一点。还需要定义您希望地图包含 every 键还是只包含 some 键。我选择了 every 案例,如果你想要 some 版本,只需将 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 的建议进行了简化
已显示正确答案,但我想指出另一个优雅的解决方案,该解决方案假定了解地图值。当您确定它们是真实的时(即:不是 nil
也不是 false
):
(every? m ks)
这是因为映射是(一元)函数,return 参数对应的值。但请注意 ({:x nil} :x) => nil
.
这是另一个使用 clojure.set
的解决方案,适用于非真实值:
(require '[clojure.set :as set])
(defn contains-many? [m & ks]
(empty? (set/difference (set ks) (set (keys m)))))
您可以利用 clojure.set/subset?
(clojure.set/subset?
#{:position :velocity}
(set (keys mario)))