我想编写一个函数来检查映射是否是另一个映射的子集.
用法的一个例子应该是:
(map-subset? {:a 1 :b 2} {:a 1 :b 2 :c 3})
=> true
Run Code Online (Sandbox Code Playgroud)
有原生方式吗?
小智 14
通过将地图转换为集合,您可以使用 clojure.set/subset?
(clojure.set/subset? (set {:a 1 :b 2}) (set {:a 1 :b 2 :c 3}))
=> true
Run Code Online (Sandbox Code Playgroud)
这将使每对地图成为集合中的一个元素
(set {:a 1 :b 2 :c 3})
=> #{[:b 2] [:c 3] [:a 1]}
Run Code Online (Sandbox Code Playgroud)
因此,{:a 1 :b 3}不会是一个子集
(clojure.set/subset? (set {:a 1 :b 3}) (set {:a 1 :b 2 :c 3}))
=> false
Run Code Online (Sandbox Code Playgroud)
(defn submap?
"Checks whether m contains all entries in sub."
[^java.util.Map m ^java.util.Map sub]
(.containsAll (.entrySet m) (.entrySet sub)))
Run Code Online (Sandbox Code Playgroud)
REPL演示:
(submap? {:foo 1 :bar 2 :quux 3} {:foo 1 :bar 2})
;= true
(submap? {:foo 1 :bar 2 :quux 3} {:foo 1 :bar 3})
;= false
(submap? {:foo 1 :bar 2} {:foo 1 :bar 2 :quux 3})
;= false
Run Code Online (Sandbox Code Playgroud)
另一种选择可能是:
(defn submap? [a b]
(= a (select-keys b (keys a))))
Run Code Online (Sandbox Code Playgroud)
这只会检查第一张地图中键的权益。
对子集的含义做出假设(该定义的直接翻译):
(and (every? (set (keys m1)) (keys m2)) ;; subset on keys
(every? #(= (m1 %)(m2 %)) (keys m2))) ;; on that subset all the same values
Run Code Online (Sandbox Code Playgroud)