使用带有动态函数的clojure过滤器

时间:2017-12-14 16:04:26

标签: clojure

我正在定义一个函数,它接受一个要重新格式化为函数的数组。 此返回的函数是过滤器命令的第一个参数。 第二个参数是我已经定义的这个表

(def persons '({:id 1 :name "olleš"} {:id 2 :name "anna"} {:id 3 :name "isak"} {:id 4 :name "beatrice"}))

当我运行我的过滤器命令

seminar.core=> (filter (fn [word func arg] (func word arg)) [:id > 2] persons)

我收到此错误

ArityException Wrong number of args (3) passed to: core/filter  clojure.lang.AFn.throwArity (AFn.java:429)

我希望我的过滤功能与下面的过滤功能类似

(filter #(< (:id %) 2) persons)
({:id 1, :name "olle"})

2 个答案:

答案 0 :(得分:1)

这是部分申请的工作:

(filter 
  (partial
    (fn [word func arg item] (func (word item) arg))
    :id > 2)
  persons)

在这里,我们创建了已填写wordfuncarg的函数的部分应用版本,并留下另一个参数 - item - 对要过滤的项目打开。

答案 1 :(得分:1)

对于简单的东西,我只会使用匿名函数:

(filter #(> (:id %) 2) persons) 

    => ({:id 3, :name "isak"} {:id 4, :name "beatrice"})

另一种解决方案是编写谓词生成函数,而不是内联函数。

(defn build-pred
  [word func arg]
  (fn [item]
    (func (word item) arg)))

(filter (build-pred :id > 2) persons))

  => ({:id 3, :name "isak"} {:id 4, :name "beatrice"})

如果你真的想将args作为向量传递,只需使用destructuring:

(defn build-pred-vec
  [[word func arg]]
  (fn [item]
    (func (word item) arg)))

(filter (build-pred-vec [:id > 2]) persons)