How to apply values to multiple functions in Clojure?

Basically, I need to do something like map, but instead of applying a function to all elements in a collection, I need to apply the same (set of) value(s) to a collection of functions (does this operation have a name?). This might seem like a simple question, but I haven't found an idiomatic way to do it in Clojure. For the special case where I need to apply only one value to each function, for example, I have used

(for [f funs] (f value))

where value is, of course, the value I need each function to take as an argument, and funs is the collection of functions which need to be called with value as the argument.

My question is, then, is there a function in Clojure that does this, but is also generalised for arbitrary numbers of arguments? Or is the above indeed idiomatic Clojure?

Upvotes: 10

Views: 5470

Answers (2)

LawZero
LawZero

Reputation: 91

From a section of CLOJURE for the BRAVE and TRUE

Another fun thing you can do with map is pass it a collection of functions. You could use this if you wanted to perform a set of calculations on different collections of numbers, like so:

(def sum #(reduce + %))
(def avg #(/ (sum %) (count %)))
(defn stats
  [numbers]
  (map #(% numbers) [sum count avg]))

(stats [3 4 10])
; => (17 3 17/3)

(stats [80 1 44 13 6])
; => (144 5 144/5)

Upvotes: 9

sloth
sloth

Reputation: 101072

You're looking for juxt

juxt

Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b c) x) => [(a x) (b x) (c x)]

Upvotes: 23

Related Questions