Existe-t-il un équivalent javascript de la fonction zip de Python? Autrement dit, étant donné que plusieurs tableaux de longueurs égales créent un tableau de paires.
Par exemple, si j'ai trois tableaux qui ressemblent à ceci:
var array1 = [1, 2, 3];
var array2 = ['a','b','c'];
var array3 = [4, 5, 6];
Le tableau de sortie doit être:
var output array:[[1,'a',4], [2,'b',5], [3,'c',6]]
forEach
,reduce
,map
,every
, etc. C'était le cas quizip
n'a pas « faire la coupe » (unflatMap
est également absent), et non pour des considérations de performance - mais pour être juste, .NET (3.5) n'a pas eu de Zip sur Enumerable pendant quelques années! Toute bibliothèque «fonctionnelle» comme le soulignement / lodash (lodash 3.x a une évaluation de séquence paresseuse) fournira une fonction zip équivalente.Réponses:
Mise à jour 2016:
Voici une version Ecmascript 6 plus brillante:
Illustration équiv. vers Python {
zip(*args)
}:(et FizzyTea souligne que ES6 a une syntaxe d'argument variadique, donc la définition de fonction suivante agira comme python, mais voir ci-dessous pour l'avertissement ... ce ne sera pas son propre inverse donc
zip(zip(x))
ne sera pas égalx
; bien que Matt Kramer le soulignezip(...zip(...x))==x
(comme en python normalzip(*zip(*x))==x
))Définition alternative équiv. vers Python {
zip
}:(Notez que la
...
syntaxe peut avoir des problèmes de performances à ce stade, et peut-être à l'avenir, donc si vous utilisez la deuxième réponse avec des arguments variadiques, vous voudrez peut-être la tester.)Voici un oneliner:
Ce qui précède suppose que les tableaux sont de taille égale, comme ils devraient l'être. Il suppose également que vous transmettez un seul argument de liste de listes, contrairement à la version de Python où la liste d'arguments est variadique. Si vous voulez toutes ces "fonctionnalités", voir ci-dessous. Il faut environ 2 lignes de code supplémentaires.
Les éléments suivants imiteront le
zip
comportement de Python dans les cas de périphérie où les tableaux ne sont pas de taille égale, en prétendant silencieusement que les parties les plus longues des tableaux n'existent pas:Cela imitera le
itertools.zip_longest
comportement de Python , en insérantundefined
où les tableaux ne sont pas définis:Si vous utilisez ces deux dernières versions (variadic aka. Versions à arguments multiples), alors zip n'est plus son propre inverse. Pour imiter l'
zip(*[...])
idiome de Python, vous devrez le fairezip.apply(this, [...])
lorsque vous souhaitez inverser la fonction zip ou si vous souhaitez également avoir un nombre variable de listes en entrée.addendum :
Pour que cette poignée soit itérable (par exemple en Python que vous pouvez utiliser
zip
sur des chaînes, des plages, des objets de carte, etc.), vous pouvez définir les éléments suivants:Cependant, si vous écrivez
zip
de la manière suivante , même cela ne sera pas nécessaire:Démo:
(Ou vous pouvez utiliser une
range(...)
fonction de style Python si vous en avez déjà écrite une. Finalement, vous pourrez utiliser des générateurs ou des compréhensions de tableaux ECMAScript.)la source
zip = (...rows) => [...rows[0]].map((_,c) => rows.map(row => row[c]));
zip(zip(x)) = x
, vous pouvez toujours vous en douterzip(...zip(...x)) = x
.const the_longest_array_length = Math.max(...(arrays.map(array => array.length)));
Découvrez la bibliothèque Underscore .
- Dis aux gens qui l'ont fait
J'ai récemment commencé à l'utiliser spécifiquement pour la
zip()
fonction et cela a laissé une excellente première impression. J'utilise jQuery et CoffeeScript, et cela va parfaitement avec eux. Underscore reprend là où ils se sont arrêtés et jusqu'à présent, il ne m'a pas déçu. Oh au fait, ce n'est que 3 Ko minifiés.Vérifiez-le:
la source
En plus de l'excellente et complète réponse de ninjagecko, tout ce qu'il faut pour compresser deux tableaux JS en un "tuple-mimic" est:
Explication:
Puisque Javascript n'a pas de
tuples
type, les fonctions pour les tuples, les listes et les ensembles n'étaient pas une priorité élevée dans la spécification du langage.Sinon, un comportement similaire est accessible de manière simple via Array map dans JS> 1.6 . (
map
est en fait souvent implémenté par les fabricants de moteurs JS dans de nombreux moteurs> JS 1.4, bien qu'il ne soit pas spécifié).La principale différence de Python
zip
,izip
... les résultats demap
style fonctionnel de », étant donné quemap
nécessite une fonction argument. De plus, c'est une fonction de l'Array
instance. On peut utiliser à laArray.prototype.map
place, si une déclaration supplémentaire pour l'entrée est un problème.Exemple:
Résultat:
Performances associées:
Utilisation de
map
sur-for
boucles:Voir: Quel est le moyen le plus efficace de fusionner [1,2] et [7,8] en [[1,7], [2,8]]
Remarque: les types de base tels que
false
etundefined
ne possèdent pas de hiérarchie d'objet prototypique et n'exposent donc pas detoString
fonction. Par conséquent, ceux-ci sont affichés comme vides dans la sortie. Le deuxième argument deAs
parseInt
est la base / nombre radix, en laquelle convertir le nombre, et puisquemap
passe l'index comme deuxième argument à sa fonction argument, une fonction wrapper est utilisée.la source
aIn.map(function(e, i) {return [e, aOut[i]];})
qu'est-ce qui ne va pas?Array.prototype.map
aurait dû l'êtreArray.prototype.map.call
, a corrigé la réponse.Exemple ES6 moderne avec un générateur:
Tout d'abord, nous obtenons une liste d'itérables en tant que
iterators
. Cela se produit généralement de manière transparente, mais ici, nous le faisons explicitement, car nous cédons étape par étape jusqu'à ce que l'un d'eux soit épuisé. Nous vérifions si l'un des résultats (en utilisant la.some()
méthode) dans le tableau donné est épuisé, et si c'est le cas, nous rompons la boucle while.la source
Parallèlement à d'autres fonctions de type Python,
pythonic
offre unezip
fonction, avec l'avantage supplémentaire de renvoyer un paresseux évaluéIterator
, similaire au comportement de son homologue Python :Divulgation Je suis auteur et mainteneur de Pythonic
la source
Le Python a deux fonctions: zip et itertools.zip_longest. L'implémentation sur JS / ES6 est comme ceci:
Implémentation du zip de Python sur JS / ES6
Résultats:
Implémentation de zip_longest de Python sur JS / ES6
( https://docs.python.org/3.5/library/itertools.html?highlight=zip_longest#itertools.zip_longest )
Résultats:
la source
Vous pouvez faire fonctionner l'utilitaire en utilisant ES6.
Cependant, dans la solution ci-dessus, la longueur du premier tableau définit la longueur du tableau de sortie.
Voici la solution dans laquelle vous avez plus de contrôle sur elle. C'est un peu complexe mais ça vaut le coup.
la source
1. Module Npm:
zip-array
J'ai trouvé un module npm qui peut être utilisé comme une version javascript de python
zip
:zip-array - Un équivalent javascript de la fonction zip de Python. Fusionne ensemble les valeurs de chacun des tableaux.
https://www.npmjs.com/package/zip-array
2.
tf.data.zip()
dans Tensorflow.jsUn autre choix alternatif est pour les utilisateurs de Tensorflow.js: si vous avez besoin d'une
zip
fonction en python pour travailler avec des jeux de données tensorflow en Javascript, vous pouvez utilisertf.data.zip()
dans Tensorflow.js.tf.data.zip () dans Tensorflow.js documenté à ici
la source
Pas intégré à Javascript lui-même. Certains des cadres Javascript courants (tels que Prototype) fournissent une implémentation, ou vous pouvez écrire le vôtre.
la source
Comme @Brandon, je recommande la fonction zip d' Underscore . Cependant, il agit comme suit:
zip_longest
undefined
valeurs au besoin pour renvoyer quelque chose de la longueur de l'entrée la plus longue.J'ai utilisé la
mixin
méthode pour étendre le trait de soulignement avec unzipShortest
, qui agit comme Pythonzip
, basé sur la propre sourcezip
de la bibliothèque pour .Vous pouvez ajouter ce qui suit à votre code JS commun, puis l'appeler comme s'il faisait partie du trait de soulignement:
_.zipShortest([1,2,3], ['a'])
retours[[1, 'a']]
, par exemple.la source
Vous pouvez réduire le tableau de tableaux et mapper un nouveau tableau en prenant le résultat de l'index du tableau interne.
la source
Une variante de la solution de générateur paresseux :
Et voici l'idiome classique du "n-groupe" du python
zip(*[iter(a)]*n)
:la source
La bibliothèque Mochikit fournit cela et bien d'autres fonctions de type Python. Le développeur de Mochikit est également un fan de Python, il a donc le style général de Python, ainsi que l'encapsulation des appels asynchrones dans un cadre de type tordu.
la source
Je me suis lancé dans JS pur en me demandant comment les plugins postés ci-dessus ont fait le travail. Voici mon résultat. Je préfère ceci en disant que je n'ai aucune idée de la stabilité de ce sera dans IE et autres. C'est juste une maquette rapide.
Ce n'est pas à l'épreuve des balles, mais c'est quand même intéressant.
la source
console.log
àalert
.document.write()
jsfiddle.net/PyTWw/5Cela rase une ligne de la réponse basée sur itérateur de Ddi :
la source
Si vous êtes bien avec ES6:
la source