开发者

Applying multiple filters to a collection in a thrush in Clojure

The following code

(let [coll [1 2 3 4 5]
      filters [#(> % 1) #(< % 5)]]
  (->> coll
       (filter (first filters))
       (filter (second filters))))

Gives me

(2 3 4)

Which is great,开发者_开发技巧 but how do I apply all the filters in coll without having to explicitly name them?

There may be totally better ways of doing this, but ideally I'd like to know an expression that can replace (filter (first filters)) (filter (second filters)) above.

Thanks!


Clojure 1.3 has a new every-pred function, which you could use thusly:

(filter (apply every-pred filters) coll)


This should work :-

(let [coll [1 2 3 4 5]
      filters [#(> % 1) #(< % 5)]]
  (filter (fn [x] (every? #(% x) filters)) coll)
)


I can't say I'm very proud of the following, but at least it works and allows for infinite filters:

(seq 
  (reduce #(clojure.set/intersection 
          (set %1) 
          (set %2)) (map #(filter % coll) filters)))

If you can use sets in place of seqs it would simplify the above code as follows:

(reduce clojure.set/intersection (map #(filter % coll) filters))


(let [coll [1 2 3 4 5]
      filters [#(> % 1) #(< % 5)]]
  (reduce (fn [c f] (filter f c)) coll filters))
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜