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 que no me faltaba una función en Core o Contrib.
Hay un espacio de nombres zip en Core, pero se describe como proporcionar acceso a la técnica funcional Zipper, que no parece ser lo que busco.
¿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 que la función sea innecesaria?
zip
función en la biblioteca de Tupelo: cloojure.github.io/doc/tupelo/tupelo.core.html#var-zipRespuestas:
hace lo que quieres:
Haskell necesita una colección de
zipWith
(zipWith3
,zipWith4
, ...) funciones, ya que todos tenemos que ser de un determinado tipo ; en particular, el número de listas de entrada que aceptan debe corregirse. (Elzip
,zip2
,zip3
, ... familia puede ser considerada como una especialización de lazipWith
familia para el caso de uso común de tupling).En contraste, Clojure y otros Lisps tienen buen soporte para funciones de aridad variable;
map
es uno de ellos y se puede usar para "tupling" de una manera similar a la de HaskellLa forma idiomática de construir una "tupla" en Clojure es construir un vector corto, como se muestra arriba.
(Solo para completar, tenga en cuenta que Haskell con algunas extensiones básicas sí permite funciones de arity variables; sin embargo, su uso requiere una buena comprensión del lenguaje, y el Haskell 98 de vainilla probablemente no las admita en absoluto, por lo tanto, las funciones de arity fijas son preferibles para la biblioteca estándar).
fuente
zip
cuando las colecciones no tienen la misma longitud. Ruby continuará procesando y suministrandonil
s para la colección más corta, mientras que Clojure dejará de procesar una vez que se agote una de las colecciones.zip
comporta como Clojuremap
a este respecto.o más generalmente
fuente
fuente
para darle exactamente lo que quería, el mapeo
list
en 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ía con cualquier cosa. y las entradas no necesitan ser del mismo tipo. map crea seqs a partir de ellos y luego asigna las seqs para que cualquier entrada seq'able funcione bien.fuente
La forma integrada sería simplemente la función 'intercalar':
fuente
(partition 2 (interleave [1 2 3 4][5 6 7 8]))
Hay una función llamada zipmap, que puede tener un efecto similar, (zipmap
(1 2 3)
(4 5 6)) La salida es como fllows: {3 6, 2 5, 1 4}fuente
# (aplicar lista de mapas%) transpone una matriz al igual que la función Python zip *. 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))
fuente