Search code examples
dictionaryclojure

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?


Solution

  • 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 +.