Pour une raison quelconque, je ne trouve pas cette chose simple dans la documentation MDN (peut-être que je la manque).
Je m'attendais à ce que cela fonctionne:
const map = new Map({foo: 'bar'});
map.get('foo'); // 'bar'
... mais la première ligne jette TypeError: (var)[Symbol.iterator] is not a function
Comment créer une carte à partir d'un objet ordinaire? Dois-je vraiment d'abord le convertir en un tableau de tableaux de paires clé-valeur?
javascript
ecmascript-6
callum
la source
la source
Object.entries
est vraiment la meilleure approcheObject.keys
, et l'approche de la fonction de générateur de bergi est légèrement plus directe que soitObject.keys
ouObject.entries
.Réponses:
Oui, le
Map
constructeur prend un tableau de paires clé-valeur.Object.entries
est une nouvelle méthode statique d'objets disponible dans ES2017 (19.1.2.5) .Il est actuellement implémenté dans Firefox 46+ et Edge 14+ et les versions plus récentes de Chrome
Si vous avez besoin de prendre en charge des environnements plus anciens et que la transpilation n'est pas une option pour vous, utilisez un polyfill, tel que celui recommandé par georg:
la source
Object.entries = obj => Object.keys(obj).map(k => [k, obj[k]])
Object.entries
a atterri dans Node 7.x proprement dit (sans drapeau) btwVeuillez voir la réponse de nils en utilisant
Object.entries
et / ou la réponse de bergi en utilisant une fonction de générateur . Bien queObject.entries
n'étant pas encore dans les spécifications lorsque la question a été posée, elle était à l'étape 4 , donc sûr à polyfill et à utiliser même en avril 2016 (juste). (Plus d'informations sur les étapes ici .) Et les fonctions du générateur étaient dans ES2015. L'OP a spécifiquement demandé d'éviter les intermédiaires, et bien que le générateur n'évite pas complètement cela, il fait un meilleur travail que le ci-dessous ou (légèrement)Object.enties
.FWIW, en utilisant
Object.entries
:[name, value]
tableaux à passernew Map
Map
constructeur appelle une fonction sur le tableau pour obtenir un itérateur; le tableau crée et renvoie un objet interateur de tableau.Map
constructeur utilise cet objet itérateur pour obtenir les entrées (les[name, value]
tableaux) et construire la carteUtilisation du générateur:
Map
constructeur appelle une fonction sur cet objet générateur pour en obtenir un itérateur; le rendement de l' objet générateur lui - mêmeMap
constructeur utilise l'objet générateur (comme itérateur) pour récupérer les entrées (les[name, value]
tableaux) et construire la carteDonc: un intermédiaire en moins (le tableau de
Object.entries
).Cependant, l'utilisation
Object.entries
est plus simple et la création de ce tableau n'est pas un problème 99,999% du temps. Alors vraiment, l'un ou l'autre. Mais ils sont tous les deux meilleurs que ceux ci-dessous. :-)Réponse originale:
Pour initialiser a
Map
, vous pouvez utiliser n'importe quel itérateur qui renvoie des paires clé / valeur sous forme de tableaux, comme un tableau de tableaux:Il n'y a pas de conversion intégrée d'objet en carte, mais c'est facile à faire avec
Object.keys
:Vous pouvez, bien sûr, vous donner une fonction de travailleur pour gérer cela:
ensuite
Ou voici une version plus l33t (est-ce toujours une chose?):
(Oui,
Map#set
renvoie la référence de la carte. Certains diront qu'il s'agit d'un abus dereduce
.)Ou nous pouvons vraiment exagérer sur l'obscurité:
Non, je ne ferais jamais ça pour de vrai. :-)
la source
var buildMap2 = o => new Map(Object.keys(o).map(k => [k, o[k]]));
.new Map(Object.entries(object))
stackoverflow.com/a/36644558/798133Non, un itérateur de tableaux de paires clé-valeur suffit. Vous pouvez utiliser ce qui suit pour éviter de créer le tableau intermédiaire:
la source
if(!obj.hasOwnProperties(key)) continue;
juste après la condition de boucle for pour vous assurer que vous ne donnez pas les propriétés héritées du prototype d'objet (à moins que vous ne fassiez confiance à l'objet, mais que vous devriez le faire quand même lors de l'itération d'objets en utilisantin
comme une bonne habitude)..hasOwnProperty
propriété et vous devrez utiliserObject.prototype.hasOwnProperty.call(obj, key)
call
. Toutes les conventions qui recommandentobj.hasOwnProperties(key)
semblent n'avoir aucune idée de ce qu'elles font.Object
en unMap
est une opération coûteuse et l'OP a spécifiquement demandé une solution sans intermédiaires. Alors pourquoi n'est-ce pas la réponse exceptée? Eh bien, demander ceci est probablement futile, cela m'énerve.function* entries<T>(obj: T): Generator<readonly [keyof T, T[keyof T]]> {…}
. Aussiyield [key, obj[key]] as const;
aiderait tapuscrit se rendre compte qu'il est tuples rendement, pas de tableaux.La réponse de Nils décrit comment convertir des objets en cartes, ce que j'ai trouvé très utile. Cependant, l'OP se demandait également où se trouvaient ces informations dans la documentation MDN. Bien qu'il ne soit peut-être pas là lorsque la question a été initialement posée, elle se trouve maintenant sur la page MDN pour Object.entries () sous l'en-tête Conversion d'un objet en carte qui indique:
la source
la source
var buildMap2 = o => new Map(Object.keys(o).map(k => [k, o[k]]));
.Vous pouvez également utiliser la méthode lodash toPairs :
la source
ES6
convertir un objet en carte:
convertir la carte en objet:
Remarque: la fonction mapToObj suppose que les clés de mappage sont des chaînes (échoueront sinon)
la source
Avec l'aide de quelques JQuery,
la source