我刚开始学习Clojure,并且我已经习惯于使用其他函数式语言来创建一些具有如下函数的管道
val result = filter(something)
map(something)
reduce(something)
collection我正在尝试使用Clojure组合两个filter函数来实现类似的功能
(defn filter-1 [array] (filter
(fn [word] (or (= word "politrons") (= word "hello"))) array))
(defn filter-2 [array] (filter
(fn [word] (= word "politrons")) array))
(def result (filter-1 ["hello" "politrons" "welcome" "to" "functional" "lisp" ""]))
(println "First:" result)
(println "Pipeline:" ((filter-2 result)))但我不能让它工作。
您是否可以提供一些建议或文档,说明如何为同一个collection组合两个predicate函数
问候
发布于 2021-01-18 18:34:13
您的两个filter-$函数已经完全成熟(请注意,通过使您的谓词函数而不是隐藏谓词的整个过滤,您将获得更多的可重用性)。
因此,要使其工作,可以使用线程最后一个宏->>
(->> array
filter-1
filter-2)这是一种相当通用的方法,你会经常在野外的代码中看到。更一般的情况:
(->> xs
(filter pred?)
(map tf)
(remove pred?))较新的方法是transducers,它通过comp完成组合。这也是将整个转换管道实际合并到一个新函数中的方法。
例如。
(def my-xf
(comp
(filter pred1)
(filter pred2)))
(into [] my-xf xs)请注意在filter上使用的是单参数版本。
发布于 2021-01-18 18:40:44
有一些选项可以组成处理步骤:
您可以像这样对调用进行管道过滤:
(->> data
(filter #{"politrons" "hello"})
(filter #{"politrons"}))
;;=> ("politrons")请注意,这些单词集将用作过滤函数(只是您的那些相等谓词的快捷方式)
但我猜你需要知道的是transducers的概念,因为它的用法包括(但不限于)你需要的这种类型的流水线:
(eduction (filter #{"politrons" "hello"})
(filter #{"hello"})
data)
;;=> ("hello")如果您只需要过滤,您还可以将过滤函数与更高级别的函数(如every-pred )结合使用
(filter (every-pred #{"politrons" "hello"}
#(= "olleh" (clojure.string/reverse %)))
data)
;;=> ("hello")https://stackoverflow.com/questions/65772588
复制相似问题