10

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!

George
  • 3,433
  • 4
  • 27
  • 25

4 Answers4

20

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

(filter (apply every-pred filters) coll)
Dave Liepmann
  • 1,555
  • 1
  • 18
  • 22
Justin Kramer
  • 3,983
  • 1
  • 23
  • 23
13

This should work :-

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

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))
skuro
  • 13,414
  • 1
  • 48
  • 67
1
(let [coll [1 2 3 4 5]
      filters [#(> % 1) #(< % 5)]]
  (reduce (fn [c f] (filter f c)) coll filters))
manutter
  • 133
  • 1
  • 6