tutorial online example clojure
zip

online - ¿Hay un equivalente para la función Zip en Clojure Core o Contrib?



clojure vs scala (7)

En Clojure, quiero combinar dos listas para dar una lista de pares,

> (zip ''(1 2 3) ''(4 5 6)) ((1 4) (2 5) (3 6))

En Haskell o Ruby, la función se llama zip . Implementarlo no es difícil, pero quería asegurarme de no perderme una función en Core o Contrib.

Hay un espacio de nombres zip en Core, pero se described como que proporciona acceso a la técnica funcional Zipper, que no parece ser lo que estoy buscando.

¿Existe una función equivalente para combinar 2 o más listas, de esta manera, en Core?

Si no lo hay, ¿es porque hay un enfoque idiomático que hace innecesaria la función?


# (apply map list%) transpone una matriz como la función zip * de Python. Como una definición macro:

usuario => (defmacro py-zip [lst] `(aplicar lista de mapas ~ lst))

# ''usuario / py-zip

usuario => (py-zip ''((1 2 3 4) (9 9 9 9) (5 6 7 8)))

((1 9 5) (2 9 6) (3 9 7) (4 9 8))

usuario => (py-zip ''((1 9 5) (2 9 6) (3 9 7) (4 9 8)))

((1 2 3 4) (9 9 9 9) (5 6 7 8))


Hay una función llamada zipmap, que puede tener el mismo efecto, (zipmap (1 2 3) (4 5 6)) La salida es como fllows: {3 6, 2 5, 1 4}


La forma integrada sería simplemente la función ''intercalar'':

(interleave [1 2 3 4] [5 6 7 8]) => [1 5 2 6 3 7 4 8]


para darle exactamente lo que quería, la list mapeo entre las dos listas le dará una lista de listas como en su ejemplo. Creo que muchos Clojurianos tenderían a usar vectores para esto, aunque funcionará con cualquier cosa. y las entradas no necesitan ser del mismo tipo. map crea seqs de ellos y luego mapea los seqs para que cualquier entrada seq''able funcione bien.

(map list ''(1 2 3) ''(4 5 6)) (map list [1 2 3] ''(4 5 6)) (map hash-map ''(1 2 3) ''(4 5 6)) (map hash-set ''(1 2 3) ''(4 5 6))


(map vector ''(1 2 3) ''(4 5 6))

hace lo que quieres:

=> ([1 4] [2 5] [3 6])

Haskell necesita una colección de zipWith ( zipWith3 , zipWith4 , ...), porque todas deben ser de un tipo específico; en particular, la cantidad de listas de entrada que aceptan debe ser reparada. (La familia zip , zip2 , zip3 , ... se puede considerar como una especialización de la familia zipWith para el caso de uso común de tupling).

En contraste, Clojure y otros Lisps tienen buen soporte para funciones de aria variable; map es uno de ellos y puede usarse para "tupling" de forma similar a Haskell''s

zipWith (/x y -> (x, y))

La forma idiomática de construir una "tupla" en Clojure es construir un vector corto, como se muestra arriba.

(Para completar, tenga en cuenta que Haskell con algunas extensiones básicas permite funciones de aria variable; sin embargo, su uso requiere una buena comprensión del lenguaje, y el vandalismo Haskell 98 probablemente no las admite en absoluto, por lo que las funciones de aria fija son preferibles para la biblioteca estándar.)


(map vector [1 2 3] [4 5 6])


(partition 2 (interleave ''(1 2 3) ''(4 5 6))) => ((1 4) (2 5) (3 6))

o más en general

(defn zip [& colls] (partition (count colls) (apply interleave colls))) (zip ''( 1 2 3) ''(4 5 6)) ;=> ((1 4) (2 5) (3 6)) (zip ''( 1 2 3) ''(4 5 6) ''(2 4 8)) ;=> ((1 4 2) (2 5 4) (3 6 8))