Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apply a function to each element of an unspecified number of vectors

Say I have two vectors:

(def x [1 2 3])
(def y [4 5 6]) 

and I want to apply a function (e.g., +) to each element in these vectors sequentially, like so:

(defn mapply
  [x y]
  (map + x y))

This function works just fine, producing (5 7 9). Now, I want to be more generic and apply the function over potentially any number of vectors. My initial thought is that I need the & parameter.

(defn mapply
  [& vecs]
  (map + vecs))

Clearly, this doesn't work and throws the error:

Cannot cast clojure.lang.PersistentVector to java.lang.Number

Presumably, I need to unpack vecs into individual vectors, but I don't know how many there will be so I'm not sure how to destructure vecs appropriately. My mind goes to apply next to explode vecs into separate vectors, perhaps something like this:

(defn mapply
  [& vecs]
  (apply (fn [& stuff] (map + stuff)) vecs))

but I think this is essentially more code doing exactly the same thing.

How would I go about making this function accept any number of vectors?

like image 646
Lyngbakr Avatar asked Sep 13 '25 03:09

Lyngbakr


2 Answers

I would try something like this:

(defn mapply [& vecs]
  (apply map + vecs))

(mapply [1 2 3] [10 40 60] [1000 10000 1000000])
;; => (1011 10042 1000063)

See the documentation for apply. We use the form (apply f x args) where f is map and x is +.

like image 161
Rulle Avatar answered Sep 15 '25 01:09

Rulle


@Rulle's answer is correct.

Your name mapply makes one expect a very generic map-and-apply where one can pass the function explicitly - but you assume it always to be +.

Maybe you should give the possibility to enter the function-for-the-map explicitly.

And call your function map-+:

(defn mapply [fun & vecs]
  (apply map fun vecs))

(defn mapply-+ [& vecs]
  (apply mapply + vecs))

(mapply-+ [1 2 3] [10 40 60] [1000 10000 1000000])
;; => (1011 10042 1000063)
like image 20
Gwang-Jin Kim Avatar answered Sep 15 '25 01:09

Gwang-Jin Kim