Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在clojure中检查一个映射是否是另一个映射的子集?_Clojure - Fatal编程技术网

如何在clojure中检查一个映射是否是另一个映射的子集?

如何在clojure中检查一个映射是否是另一个映射的子集?,clojure,Clojure,我想写一个函数来检查一个映射是否是另一个映射的子集 用法示例应为: (map-subset? {:a 1 :b 2} {:a 1 :b 2 :c 3}) => true 有没有本地的方法可以解决这个问题?有很多可能的方法可以解决你的问题。一个快速可行的解决办法是: (defn contains-submap? [map-structure keys] (every? (partial contains? map-structure) keys)) (contains-subma

我想写一个函数来检查一个映射是否是另一个映射的子集

用法示例应为:

(map-subset? {:a 1 :b 2} {:a 1 :b 2 :c 3})
=> true

有没有本地的方法可以解决这个问题?

有很多可能的方法可以解决你的问题。一个快速可行的解决办法是:

(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所指出的,这取决于你最初的意图。

假设你所说的子集(该定义的直接翻译)是什么意思:

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

通过将映射转换为集合,您可以使用
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]}
因此,
{:a1:b3}
将不是一个子集

(clojure.set/subset? (set {:a 1 :b 3}) (set {:a 1 :b 2 :c 3}))
=> false

另一个选择是:

(defn submap? [a b]
  (= a (select-keys b (keys a))))

这将只检查第一个映射中键的公平性。

假设您希望键和值匹配

有没有一种本地的方法可以做到这一点

没有标准函数。我建议

(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

如果这两个都不重要,可以选择更优雅的版本,例如

你所说的这个子集关系的定义是什么?在这种情况下,是否首选类型提示?如果是,请告诉我原因好吗?@Chiron因为如果没有它们,所有三个方法调用都将是反射性的,函数将非常慢。添加了类型提示后,我希望这是最快的解决方案之一。
(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