¿Existe un javascript equivalente a la función zip de Python? Es decir, dadas múltiples matrices de igual longitud crean una matriz de pares.
Por ejemplo, si tengo tres matrices que se ven así:
var array1 = [1, 2, 3];
var array2 = ['a','b','c'];
var array3 = [4, 5, 6];
La matriz de salida debe ser:
var output array:[[1,'a',4], [2,'b',5], [3,'c',6]]
forEach
,reduce
,map
,every
, etc. Fue simplemente el caso de quezip
no "hacer el corte" (unaflatMap
también está ausente), no por consideraciones de rendimiento - pero para ser justos, .NET (3.5) no tuvo un Zip en Enumerable durante un par de años. Cualquier biblioteca 'funcionalista' como el subrayado / lodash (lodash 3.x tiene evaluación de secuencia diferida) proporcionará una función zip equivalente.Respuestas:
Actualización 2016:
Aquí hay una versión más elegante de Ecmascript 6:
Ilustración equiv. a Python {
zip(*args)
}:(y FizzyTea señala que ES6 tiene una sintaxis de argumento variable, por lo que la siguiente definición de función actuará como python, pero vea a continuación el descargo de responsabilidad ... esto no será su propio inverso, por
zip(zip(x))
lo que no será igualx
; aunque como señala Matt Kramerzip(...zip(...x))==x
(como en pitón normalzip(*zip(*x))==x
))Definición alternativa equiv. a Python {
zip
}:(Tenga en cuenta que la
...
sintaxis puede tener problemas de rendimiento en este momento, y posiblemente en el futuro, por lo que si usa la segunda respuesta con argumentos variables, es posible que desee probarla).Aquí hay una línea:
Lo anterior supone que las matrices son del mismo tamaño, como deberían ser. También supone que pasa una sola lista de argumentos de listas, a diferencia de la versión de Python donde la lista de argumentos es variada. Si desea todas estas "características", consulte a continuación. Solo toma alrededor de 2 líneas adicionales de código.
Lo siguiente imitará el
zip
comportamiento de Python en casos extremos donde las matrices no son del mismo tamaño, simulando en silencio que las partes más largas de las matrices no existen:Esto imitará el
itertools.zip_longest
comportamiento de Python , insertandoundefined
donde las matrices no están definidas:Si utiliza estas dos últimas versiones (también conocidas como versiones variadas de argumentos múltiples), entonces zip ya no es su propio inverso. Para imitar el
zip(*[...])
idioma de Python, deberá hacerlozip.apply(this, [...])
cuando desee invertir la función zip o si desea tener un número variable de listas como entrada.Anexo :
Para hacer que este maneje sea iterable (por ejemplo, en Python puede usar
zip
cadenas, rangos, objetos de mapa, etc.), puede definir lo siguiente:Sin embargo, si escribe
zip
de la siguiente manera , incluso eso no será necesario:Manifestación:
(O podría usar una
range(...)
función de estilo Python si ya ha escrito una. Eventualmente podrá usar comprensiones o generadores de matriz ECMAScript).fuente
zip = (...rows) => [...rows[0]].map((_,c) => rows.map(row => row[c]));
zip(zip(x)) = x
, aún puede disfrutar de la confianza de quezip(...zip(...x)) = x
.const the_longest_array_length = Math.max(...(arrays.map(array => array.length)));
Echa un vistazo a la biblioteca subrayado .
- Di las personas que lo hicieron
Recientemente comencé a usarlo específicamente para la
zip()
función y ha dejado una gran primera impresión. Estoy usando jQuery y CoffeeScript, y simplemente combina perfectamente con ellos. El guión bajo comienza justo donde lo dejan y hasta ahora no me ha decepcionado. Ah, por cierto, solo son 3kb minificados.Echale un vistazo:
fuente
Además de la excelente y completa respuesta de ninjagecko, todo lo que se necesita para comprimir dos matrices JS en una "imitación de tupla" es:
Explicación:
Dado que Javascript no tiene un
tuples
tipo, las funciones para tuplas, listas y conjuntos no tenían una alta prioridad en la especificación del lenguaje.De lo contrario, se puede acceder de manera directa a un comportamiento similar a través del mapa de matriz en JS> 1.6 . (en
map
realidad, los fabricantes de motores JS a menudo lo implementan en muchos motores> JS 1.4, a pesar de que no se especifica).La principal diferencia de Python
zip
,izip
... Resultados demap
estilo funcional 's, ya quemap
requiere una función de argumento. Además, es una función de laArray
instancia. Uno puede usarArray.prototype.map
en su lugar, si una declaración adicional para la entrada es un problema.Ejemplo:
Resultado:
Rendimiento relacionado:
Usando
map
over-for
loops:Ver: ¿Cuál es la forma más eficiente de fusionar [1,2] y [7,8] en [[1,7], [2,8]]
Nota: los tipos base como
false
yundefined
no poseen una jerarquía de objetos prototípicos y, por lo tanto, no exponen unatoString
función. Por lo tanto, estos se muestran como vacíos en la salida.Como
parseInt
el segundo argumento es la base / número de la raíz, a la cual convertir el número, y dado quemap
pasa el índice como el segundo argumento a su función de argumento, se utiliza una función de contenedor.fuente
aIn.map(function(e, i) {return [e, aOut[i]];})
¿Qué está mal?Array.prototype.map
debería haber sidoArray.prototype.map.call
, arregló la respuesta.Ejemplo moderno de ES6 con un generador:
Primero, obtenemos una lista de iterables como
iterators
. Esto generalmente ocurre de manera transparente, pero aquí lo hacemos explícitamente, ya que cedemos paso a paso hasta que uno de ellos se agote. Verificamos si alguno de los resultados (usando el.some()
método) en la matriz dada está agotado, y si es así, rompemos el ciclo while.fuente
Junto con otras funciones similares a Python,
pythonic
ofrece unazip
función, con el beneficio adicional de devolver una evaluación diferidaIterator
, similar al comportamiento de su contraparte de Python :Divulgación Soy autor y mantenedor de Pythonic
fuente
Python tiene dos funciones: zip e itertools.zip_longest. La implementación en JS / ES6 es así:
Implementación del zip de Python en JS / ES6
Resultados:
Implementación zip_longest de Python en JS / ES6
( https://docs.python.org/3.5/library/itertools.html?highlight=zip_longest#itertools.zip_longest )
Resultados:
fuente
Puede hacer que la utilidad funcione utilizando ES6.
Sin embargo, en la solución anterior, la longitud de la primera matriz define la longitud de la matriz de salida.
Aquí está la solución en la que tienes más control sobre ella. Es un poco complejo pero vale la pena.
fuente
1. Módulo Npm:
zip-array
Encontré un módulo npm que se puede usar como una versión javascript de python
zip
:conjunto de zip : un equivalente de JavaScript de la función zip de Python. Fusiona los valores de cada una de las matrices.
https://www.npmjs.com/package/zip-array
2)
tf.data.zip()
en Tensorflow.jsOtra opción alternativa es para los usuarios de Tensorflow.js: si necesita una
zip
función en python para trabajar con conjuntos de datos de tensorflow en Javascript, puede usartf.data.zip()
en Tensorflow.js.tf.data.zip () en Tensorflow.js documentado aquí
fuente
No está integrado en Javascript en sí. Algunos de los marcos JavaScript comunes (como Prototype) proporcionan una implementación, o puede escribir la suya propia.
fuente
Al igual que @Brandon, recomiendo la función zip de Underscore . Sin embargo, actúa como , agregando valores según sea necesario para devolver algo de la longitud de la entrada más larga.
zip_longest
undefined
Utilicé el
mixin
método para extender el guión bajo con azipShortest
, que actúa como Pythonzip
, basado en la propia fuentezip
de la biblioteca .Puede agregar lo siguiente a su código JS común y luego llamarlo como si fuera parte del guión bajo:
_.zipShortest([1,2,3], ['a'])
retornos[[1, 'a']]
, por ejemplo.fuente
Puede reducir la matriz de matrices y asignar una nueva matriz tomando el resultado del índice de la matriz interna.
fuente
Una variación de la solución de generador diferido :
Y este es el idioma clásico del "grupo n" de Python
zip(*[iter(a)]*n)
:fuente
La biblioteca Mochikit proporciona esta y muchas otras funciones similares a Python. El desarrollador de Mochikit también es un fanático de Python, por lo que tiene el estilo general de Python, y también envuelve las llamadas asíncronas en un marco retorcido.
fuente
Intenté esto en JS puro preguntándome cómo los complementos publicados anteriormente hicieron el trabajo. Aquí está mi resultado. Prefiero esto diciendo que no tengo idea de cuán estable será esto en IE y similares. Es solo una maqueta rápida.
No es a prueba de balas, pero sigue siendo interesante.
fuente
console.log
aalert
.document.write()
jsfiddle.net/PyTWw/5Esto elimina una línea de la respuesta basada en iterador de Ddi :
fuente
Si está bien con ES6:
fuente