Pregunta

I have been playing around with clojure, and decided to make a higher order function that combines mapcat and list to emulate this behavior:

Clojure> (mapcat list '(1 2 3 4) '(5 6 7 8))
(1 5 2 6 3 7 4 8)

my first attempt was defining mapcatList as follows:

Clojure> (defn mapcatList[& more](mapcat list more))
#'sandbox99/mapcatList
Clojure> (mapcatList '(1 2 3 4) '(5 6 7 8))
((1 2 3 4) (5 6 7 8))

Obviously the function does not behave how I would like it, and I think this is because the two lists are being put into one list and passed as a single argument, not two. I was able to remedy the situation with the following,

Clojure> (defn mapcatList[x y & more](mapcat list x y))
#'sandbox99/mapcatList
Clojure> (mapcatList '(1 2 3 4) '(5 6 7 8))
(1 5 2 6 3 7 4 8)

This solution works well with two lists, but I would like the function to work with a variable number of arguments.

My question: How can I pass a variable number of argument to a function, then destructure them so they are passed as individual arguments together to 'mapcat list'?

¿Fue útil?

Solución

You are looking for apply. This calls a function with the arguments supplied in a sequence.

But are you aware that there's a function interleave that does exactly what your mapcatList tries to do?

Otros consejos

You're right, the arguments are wrapped in a list as a result of the vararg declaration. You need to apply the arguments in order to unwrap the list of arguments:

(defn mapcatList[& more]
  (apply mapcat list more))

user=> (mapcatList '(1 2 3 4) '(5 6 7 8))               
(1 5 2 6 3 7 4 8)
user=> (mapcatList '(1 2 3 4) '(5 6 7 8) '(\a \b \c \d))
(1 5 \a 2 6 \b 3 7 \c 4 8 \d)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top