J'essaie d'utiliser le nouvel objet Map de Javascript EC6, car il est déjà pris en charge dans les dernières versions de Firefox et Chrome.
Mais je trouve cela très limité dans la programmation "fonctionnelle", car il manque des méthodes classiques de carte, de filtre, etc. qui fonctionneraient bien avec une [key, value]
paire. Il a un forEach mais qui ne renvoie PAS le résultat du rappel.
Si je pouvais transformer son map.entries()
MapIterator en un simple tableau, je pourrais alors utiliser le standard .map
, .filter
sans hacks supplémentaires.
Existe-t-il un "bon" moyen de transformer un itérateur Javascript en un tableau? En python, c'est aussi simple que de le faire list(iterator)
... mais Array(m.entries())
retournez un tableau avec l'itérateur comme premier élément !!!
ÉDITER
J'ai oublié de préciser que je cherche une réponse qui fonctionne partout où Map fonctionne, ce qui signifie au moins Chrome et Firefox (Array.from ne fonctionne pas dans Chrome).
PS.
Je sais qu'il y a le fantastique wu.js mais sa dépendance au traceur me rebute ...
la source
Réponses:
Vous recherchez la nouvelle
Array.from
fonction qui convertit les itérables arbitraires en instances de tableau:Il est désormais pris en charge dans Edge, FF, Chrome et Node 4+ .
Bien sûr, il pourrait être utile de définir
map
,filter
et des méthodes similaires directement sur l'interface iterator, de sorte que vous pouvez éviter l' allocation du tableau. Vous pouvez également utiliser une fonction de générateur au lieu de fonctions d'ordre supérieur:la source
(value, key)
paires et non des(value, index)
paires.yourTransformation = function([key, value], index) { … }
Map
a des paires clé / valeur. Par conséquent, à mon humble avis, cela n'a aucun sens de définir le généralmap
et lesfilter
fonctions des itérateurs. Au lieu de cela, chaque objet itérable doit avoir ses propres fonctionsmap
etfilter
. Cela a du sens carmap
etfilter
sont des opérations de préservation de la structure (peut-être pas,filter
mais c'estmap
certainement le cas) et par conséquent, les fonctionsmap
etfilter
doivent connaître la structure des objets itérables sur lesquels elles mappent ou filtrent. Pensez-y, dans Haskell nous définissons différentes instances deFunctor
. =)[...map.entries()]
ouArray.from(map.entries())
C'est super facile.
Quoi qu'il en soit, les itérateurs manquent de méthodes de réduction, de filtrage et similaires. Vous devez les écrire vous-même, car c'est plus efficace que de convertir Map en tableau et inversement. Mais ne faites pas de sauts Map -> Array -> Map -> Array -> Map -> Array, car cela tuerait les performances.
la source
Array.from
a déjà été couvert par @Bergi.[iterator]
ne fonctionne pas car dans Chrome, il crée un tableau avec un seuliterator
élément, et[...map.entries()]
n'est pas une syntaxe acceptée dans ChromeIl n'est pas nécessaire de transformer un
Map
fichierArray
. Vous pouvez simplement créermap
etfilter
fonctions pour lesMap
objets:Par exemple, vous pouvez ajouter un bang (c'est-à-dire un
!
caractère) à la valeur de chaque entrée d'une carte dont la clé est une primitive.Vous pouvez également ajouter
map
etfilter
méthodes surMap.prototype
pour le faire mieux lire. Bien qu'il ne soit généralement pas conseillé de modifier les prototypes natifs, je pense qu'une exception peut être faite dans le casmap
etfilter
pourMap.prototype
:Edit: Dans la réponse de Bergi, il a créé des génériques
map
etfilter
fonctions génératrices pour tous les objets itérables. L'avantage de les utiliser est que, comme ce sont des fonctions génératrices, elles n'allouent pas d'objets itérables intermédiaires.Par exemple, les fonctions my
map
etfilter
définies ci-dessus créent de nouveauxMap
objets. Par conséquent, l'appelobject.filter(primitive).map(appendBang)
crée deux nouveauxMap
objets:La création d'objets itérables intermédiaires est coûteuse. Les fonctions génératrices de Bergi résolvent ce problème. Ils n'allouent pas d'objets intermédiaires mais permettent à un itérateur de transmettre ses valeurs paresseusement au suivant. Ce type d'optimisation est connu sous le nom de fusion ou de déforestation dans les langages de programmation fonctionnels et peut améliorer considérablement les performances du programme.
Le seul problème que j'ai avec les fonctions génératrices de Bergi est qu'elles ne sont pas spécifiques aux
Map
objets. Au lieu de cela, ils sont généralisés pour tous les objets itérables. Par conséquent, au lieu d'appeler les fonctions de rappel avec des(value, key)
paires (comme je m'y attendais lors du mappage sur aMap
), il appelle les fonctions de rappel avec(value, index)
paires. Sinon, c'est une excellente solution et je recommanderais certainement de l'utiliser sur les solutions que j'ai fournies.Voici donc les fonctions de générateur spécifiques que j'utiliserais pour mapper et filtrer des
Map
objets:Ils peuvent être utilisés comme suit:
Si vous voulez une interface plus fluide, vous pouvez faire quelque chose comme ceci:
J'espère que cela pourra aider.
la source
Map
objets en utilisant des fonctionsmap
et desfilter
fonctions spécialisées . La réponse de Bergi démontre l'utilisation de génériquesmap
et defilter
fonctions pour tous les objets itérables qui ne peuvent pas être utilisés pour transformer desMap
objets car les clés de l'Map
objet sont perdues.Array.from
ne fonctionne pas dans Chrome (alors que Map et les itérateurs le font!). Mais je peux voir que l'approche est très similaire et que vous pouvez simplement ajouter la fonction "toArray" à votre groupe!toArray
fonction.Une petite mise à jour de 2019:
Désormais, Array.from semble être universellement disponible et, de plus, il accepte un deuxième argument mapFn , qui l'empêche de créer un tableau intermédiaire. Cela ressemble essentiellement à ceci:
la source
Array.from
existe déjà, c'est plus adapté pour être un commentaire ou une modification demandée à cette réponse ... mais merci!Vous pouvez utiliser une bibliothèque comme https://www.npmjs.com/package/itiriri qui implémente des méthodes de type tableau pour les itérables:
la source
Vous pouvez obtenir le tableau de tableaux (clé et valeur):
Et puis, vous pouvez facilement obtenir des valeurs de l'intérieur, comme par exemple les clés avec l'itérateur de carte.
la source
Vous pouvez également utiliser fluent-iterable pour transformer en tableau:
la source