Clojure Partial Application - How to get a "map" to return a feature set?

I have a function that I basically pulled out of the discussion in the go Clojure google group, which takes a collection and a list of functions of arbitrary length and filters it to return a new collection containing all the elements of the original list for which at least one of the functions is true :

(defn multi-any-filter [coll & funcs] (filter #(some true? ((apply juxt funcs) %)) coll)) 

I play with creating a generic solution to Project Euler Problem 1 , so I use it like this:

 (def f3 (fn [x] (= 0 (mod x 3)))) (def f5 (fn [x] (= 0 (mod x 5)))) (reduce + (multi-any-filter (range 1 1000) f3 f5)) 

Which gives the correct answer.

However, I want to change it so that I can pass ints instead of it, for example

 (reduce + (multi-any-filter (range 1 1000) 3 5)) 

where I can replace 3 and 5 with an arbitrary number int and wrap the function (= 0 (mod xy)) as an anonymous function inside a function with several filters.

Unfortunately, this is the limit of my Clojure ability. I think I need to do something with map in the argument list, but I'm not sure how to get map to return a list of functions, each of which expects a different argument. Clojure does not seem to support the way I learned how to do this in other functional languages. Maybe I need to use partial in the right place, but I'm not quite sure how to do this.

In other words, I want to be able to pass an arbitrary number of arguments (which are not functions), and then each of these arguments is wrapped in the same function, and then the list of functions is passed to juxt instead of funcs in my multi-any-filter function above .

Thanks for any tips!

+6
source share
1 answer
 (defn evenly-divisible? [xy] (zero? (mod xy))) (defn multi-any-filter [col & nums] (let [partials (map #(fn [x] (evenly-divisible? x %)) nums) f (apply juxt partials)] (filter #(some true? (f %)) col))) 

I do not use partial because it applies the arg argument in the first position of fn . Do we want it to be in the second position evenly-divisible? . Could we reorder to evenly-divisible? but then it would not look right when using standalone.

 user=> (reduce + (multi-any-filter (range 1 1000) 3 5)) 233168 
+6
source

All Articles