我想编写一个函数来检查地图是否是另一个地图的子集。
使用的一个例子应该是:
(map-subset? {:a 1 :b 2} {:a 1 :b 2 :c 3})
=> true
有原生方式吗?
答案 0 :(得分:14)
通过将地图转换为集合,您可以使用clojure.set/subset?
(clojure.set/subset? (set {:a 1 :b 2}) (set {:a 1 :b 2 :c 3}))
=> true
这会使每对地图成为集合
中的一个元素 (set {:a 1 :b 2 :c 3})
=> #{[:b 2] [:c 3] [:a 1]}
因此,{:a 1 :b 3}
不会是子集
(clojure.set/subset? (set {:a 1 :b 3}) (set {:a 1 :b 2 :c 3}))
=> false
答案 1 :(得分:9)
(defn submap?
"Checks whether m contains all entries in sub."
[^java.util.Map m ^java.util.Map sub]
(.containsAll (.entrySet m) (.entrySet sub)))
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
答案 2 :(得分:3)
另一种选择可能是:
collection @courses => :courses
attributes :id, :Title, :Credits , :department_name
这只会检查第一张地图中按键的等值。
答案 3 :(得分:1)
有许多方法可以解决您的问题。一个快速可行的解决方案是:
(defn contains-submap? [map-structure keys]
(every? (partial contains? map-structure) keys))
(contains-submap? {:a 1 :b 2 :c 3} (keys {:a 1 :b 2}))
true
例如,可以使用集合来完成。但正如@kasterma指出的那样,这取决于你原来的打算。
答案 4 :(得分:1)
假设子集的意思(该定义的直接翻译):
(and (every? (set (keys m1)) (keys m2)) ;; subset on keys
(every? #(= (m1 %)(m2 %)) (keys m2))) ;; on that subset all the same values
答案 5 :(得分:0)
假设您打算将键和值匹配...
有原生方式吗?
没有标准功能。我建议......
(defn map-subset? [a-map b-map]
(every? (fn [[k _ :as entry]] (= entry (find b-map k))) a-map))
一些例子:
(map-subset? {:a 1 :b 2} {:a 1 :b 2 :c 3})
=> true
(map-subset? {:d 4} {:a 1 :b 2 :c 3})
=> false
(map-subset? {:a 3} {:a 1 :b 2 :c 3})
=> false
(map-subset? {:a nil} {})
=> false
nil
值。如果这些都不重要,请使用更优雅的版本,例如kasterma's。