clojure - 这个 Clojure 表单是如何工作的?从另一个列表中删除一个列表

标签 clojure

我正在为类做一个项目,我偶然发现了一些已被证明有用的代码,尽管我不确定下面的行如何“读取”。我了解它所做的事情的结果,但不知道它是如何做的。

(remove #(some (partial = %) '(1 2 3 4)) '(1 2 3 5 6 7))

它的作用是从第二组中删除第一组中的值(如果可能)。因此,给定两个集合 PV,它会找到 P/V

我想我正在寻找正在发生的事情的英语句子?

编辑:标题。另外,我确实理解remove的作用,给定一些谓词,例如pos?,它会返回一个惰性项目序列,当应用谓词时,这些项目等于true。

我特别不明白的是 #(some (partial = %)) 如何计算为谓词。

最佳答案

#(some (partial = %) '(1 2 3 4))

...是...的语法糖

(fn [x] (some (partial = x) '(1 2 3 4))

...所以,打电话

(#(some (partial = %) '(1 2 3 4)) 5)

...运行...

(some (partial = 5) '(1 2 3 4))

...因此,对 '(1 2 3 4) 中的每个条目运行 (partial = 5) 直到找到匹配项 - 因此:(= 5 1)(= 5 2) 等 - 当未返回匹配项时返回 nil

nil 是错误的。因此,任何不存在匹配的序列元素都将返回 false,并由 remove 保留,而对于存在匹配的任何序列元素,谓词将返回 true 并被删除。


显然,与真实的集合算术相比,为一个序列中的每个项目创建一个 lambda 函数并根据另一个序列的内容评估这些函数的效率极低。因此,在项目数量可能不重要的任何情况下都不应使用此代码。

相反:

(clojure.set/difference
  #{1 2 3 4 5 6 7}
  #{1 2 3 4})

...将是有效且惯用的方法。如果您从列表而不是集合文字开始,则可以将其替换为 (clojure.set/difference (into #{} list-a) (into #{} list-b))(clojure.set/difference (set list-a) (set list-b))

关于clojure - 这个 Clojure 表单是如何工作的?从另一个列表中删除一个列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29616169/

相关文章:

clojure - 如何使用 ClojureScript 和 Om 根据用户输入过滤列表?

clojure - 第二个 println 语句会发生什么? (Clojure 回复)

dictionary - 如何在 clojure 中检查 map 中的重复项?

namespaces - 我可以引用另一个命名空间并将其功能公开为当前 ns 吗?

object - 在 clojure 中为对象的特定实例创建代理

clojure - 我可以将 Play 和 Akka 与 Clojure 一起使用吗?

clojure - 是否可以将特定的 JAR 添加到 nrepl 服务器使用的 Clojure 类路径中?

unix - 在 clojure 中将 unix 时间戳转换为人类可读的日期和时间

clojure - fmap 在哪里(或者如何将 fn 应用于映射的每个值)

macros - 为什么我的宏没有给出任何输出