Existe um equivalente javascript da função zip do Python? Ou seja, dadas várias matrizes de comprimentos iguais, cria uma matriz de pares.
Por exemplo, se eu tiver três matrizes parecidas com esta:
var array1 = [1, 2, 3];
var array2 = ['a','b','c'];
var array3 = [4, 5, 6];
A matriz de saída deve ser:
var output array:[[1,'a',4], [2,'b',5], [3,'c',6]]
forEach
,reduce
,map
,every
, etc. Era apenas o caso quezip
não "fazer o corte" (aflatMap
também está ausente), e não para as considerações de desempenho - mas para ser justo, o .NET (3.5) não tinha um Zip no Enumerable por alguns anos! Qualquer biblioteca 'funcional' como o sublinhado / lodash (o lodash 3.x possui uma avaliação de sequência lenta) fornecerá uma função zip equivalente.Respostas:
Atualização de 2016:
Aqui está uma versão mais ecológica do Ecmascript 6:
Ilustração equiv. para Python {
zip(*args)
}:(e o FizzyTea salienta que o ES6 tem sintaxe de argumento variada, portanto a seguinte definição de função funcionará como python, mas veja abaixo o aviso de isenção de responsabilidade ... isso não será o seu próprio inverso, portanto
zip(zip(x))
não será igualx
; embora, como Matt Kramer apontezip(...zip(...x))==x
(como em python comumzip(*zip(*x))==x
))Definição alternativa equiv. para Python {
zip
}:(Observe que a
...
sintaxe pode ter problemas de desempenho no momento e possivelmente no futuro; portanto, se você usar a segunda resposta com argumentos variados, poderá testá-la com perfeição.)Aqui está um oneliner:
O exposto acima pressupõe que as matrizes sejam do mesmo tamanho, como deveriam ser. Também assume que você passa em um único argumento da lista de listas, diferente da versão do Python, onde a lista de argumentos é variável. Se você deseja todos esses "recursos", veja abaixo. São necessárias apenas duas linhas de código extras.
A seguir, imitaremos o
zip
comportamento do Python em casos extremos onde as matrizes não são do mesmo tamanho, fingindo silenciosamente que as partes mais longas das matrizes não existem:Isso imitará o
itertools.zip_longest
comportamento do Python , inserindoundefined
onde as matrizes não estão definidas:Se você usar essas duas últimas versões (variadic, também conhecida como versões com vários argumentos), o zip não será mais o seu próprio inverso. Para imitar o
zip(*[...])
idioma do Python, você precisará fazer issozip.apply(this, [...])
quando quiser inverter a função zip ou se desejar ter um número variável de listas como entrada.adendo :
Para tornar esse manipulador iterável (por exemplo, em Python, você pode usar
zip
em strings, intervalos, objetos de mapa etc.), você pode definir o seguinte:No entanto, se você escrever
zip
da seguinte maneira , mesmo isso não será necessário:Demo:
(Ou você pode usar uma
range(...)
função Python-estilo, se você escreveu um já. Eventualmente, você será capaz de usar compreensões de matriz ECMAScript ou geradores).fonte
zip = (...rows) => [...rows[0]].map((_,c) => rows.map(row => row[c]));
zip(zip(x)) = x
, você ainda pode aproveitar a confiança dissozip(...zip(...x)) = x
.const the_longest_array_length = Math.max(...(arrays.map(array => array.length)));
Confira a biblioteca Underscore .
- Diga as pessoas que fizeram isso
Recentemente, comecei a usá-lo especificamente para a
zip()
função e deixou uma ótima primeira impressão. Estou usando jQuery e CoffeeScript, e ele combina perfeitamente com eles. Sublinhado começa exatamente onde eles param e até agora não me decepcionou. Ah, a propósito, é apenas 3kb minificado.Confira:
fonte
Além da excelente e abrangente resposta do ninjagecko, basta compactar duas matrizes JS em uma "imitação de tupla" é:
Explicação:
Como o Javascript não possui um
tuples
tipo, as funções para tuplas, listas e conjuntos não eram uma alta prioridade na especificação do idioma.Caso contrário, um comportamento semelhante é acessível de maneira direta via mapa de matriz em JS> 1.6 . (
map
na verdade, é frequentemente implementado pelos fabricantes de mecanismos JS em muitos> motores JS 1.4, apesar de não especificado).A principal diferença para Python
zip
,izip
... resultados demap
estilo funcional 's, uma vez quemap
requer uma função-argumento. Além disso, é uma função daArray
instância. Pode-se usarArray.prototype.map
, se uma declaração extra para a entrada for um problema.Exemplo:
Resultado:
Desempenho relacionado:
Usando
map
over-for
loops:Veja: Qual é a maneira mais eficiente de mesclar [1,2] e [7,8] em [[1,7], [2,8]]
Nota: os tipos de base como
false
eundefined
não possuem uma hierarquia de objetos prototípica e, portanto, não expõem umatoString
função. Portanto, eles são mostrados como vazios na saída.Como
parseInt
o segundo argumento é a base / número da raiz, para a qual converter o número e comomap
passa o índice como o segundo argumento para sua função de argumento, uma função de wrapper é usada.fonte
aIn.map(function(e, i) {return [e, aOut[i]];})
O que está errado?Array.prototype.map
deveria ter sidoArray.prototype.map.call
, corrigiu a resposta.Exemplo moderno do ES6 com um gerador:
Primeiro, obtemos uma lista de iteráveis como
iterators
. Isso geralmente acontece de forma transparente, mas aqui o fazemos explicitamente, pois produzimos passo a passo até que um deles se esgote. Verificamos se algum dos resultados (usando o.some()
método) no array especificado está esgotado e, se sim, interrompemos o loop while.fonte
Juntamente com outras funções do tipo Python,
pythonic
oferece umazip
função, com o benefício extra de retornar uma avaliação lentaIterator
, semelhante ao comportamento de sua contraparte do Python :Divulgação Sou autor e mantenedor de Pythonic
fonte
O Python tem duas funções: zip e itertools.zip_longest. A implementação em JS / ES6 é assim:
Implementação do zip do Python no JS / ES6
Resultados:
Implementação do zip_longest do Python no JS / ES6
( https://docs.python.org/3.5/library/itertools.html?highlight=zip_longest#itertools.zip_longest )
Resultados:
fonte
Você pode fazer a função de utilitário usando o ES6.
No entanto, no comprimento da solução acima da primeira matriz define o comprimento da matriz de saída.
Aqui está a solução na qual você tem mais controle sobre ela. É um pouco complexo, mas vale a pena.
fonte
1. Módulo Npm:
zip-array
Encontrei um módulo npm que pode ser usado como uma versão javascript do python
zip
:zip-array - Um equivalente javascript da função zip do Python. Mescla os valores de cada uma das matrizes.
https://www.npmjs.com/package/zip-array
2.
tf.data.zip()
no Tensorflow.jsOutra opção alternativa é para os usuários do Tensorflow.js: se você precisar de uma
zip
função em python para trabalhar com conjuntos de dados do tensorflow em Javascript, poderá usartf.data.zip()
no Tensorflow.js.tf.data.zip () no Tensorflow.js documentado aqui
fonte
Não é incorporado ao próprio Javascript. Algumas das estruturas Javascript comuns (como Prototype) fornecem uma implementação, ou você pode escrever sua própria.
fonte
Como o @Brandon, eu recomendo a função zip do Underscore . No entanto, ele age como , acrescentando
zip_longest
undefined
valores conforme necessário para retornar algo do tamanho da entrada mais longa.Eu usei o
mixin
método para estender o sublinhado com azipShortest
, que funciona como o Pythonzip
, baseado na fonte da própria bibliotecazip
.Você pode adicionar o seguinte ao seu código JS comum e chamá-lo como se fosse parte do sublinhado:
_.zipShortest([1,2,3], ['a'])
retorna[[1, 'a']]
, por exemplo.fonte
Você pode reduzir a matriz de matrizes e mapear uma nova matriz obtendo o resultado do índice da matriz interna.
fonte
Uma variação da solução do gerador lento :
E este é o idioma clássico "n-group" do python
zip(*[iter(a)]*n)
:fonte
A biblioteca Mochikit fornece essa e muitas outras funções semelhantes ao Python. O desenvolvedor do Mochikit também é um fã de Python, por isso tem o estilo geral do Python e também os envoltórios que o assíncrono chama em uma estrutura distorcida.
fonte
Eu fiz isso em JS puro, imaginando como os plug-ins postados acima fizeram o trabalho. Aqui está o meu resultado. Eu prefácio isso dizendo que não tenho idéia de quão estável isso será no IE e similares. É apenas uma maquete rápida.
Não é à prova de balas, mas ainda é interessante.
fonte
console.log
paraalert
.document.write()
jsfiddle.net/PyTWw/5Isso raspa uma linha da resposta baseada em iterador do Ddi :
fonte
Se você está bem com o ES6:
fonte