Pour une raison quelconque, je ne trouve pas cette chose simple dans la documentation MDN (peut-être me manque-t-il).
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 simple? Dois-je vraiment d'abord le convertir en un tableau de tableaux de paires clé-valeur?
Oui, le constructeur Map
prend un tableau de paires clé-valeur.
Object.entries
est une nouvelle méthode statique d'objet disponible dans ES2017 (19.1.2.5) .
const map = new Map(Object.entries({foo: 'bar'}));
map.get('foo'); // 'bar'
Il est actuellement implémenté dans Firefox 46+ et Edge 14+ et les versions plus récentes de Chrome
Si vous devez prendre en charge des environnements plus anciens et que la transpilation n'est pas une option pour vous, utilisez un polyfill, comme celui recommandé par georg:
Object.entries = typeof Object.entries === 'function' ? Object.entries : obj => Object.keys(obj).map(k => [k, obj[k]]);
Veuillez 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 que Object.entries
ne soit pas encore dans les spécifications lorsque la question a été posée, c'était à l'étape 4 , il est donc sans danger de le polyfiller et de l'utiliser dès avril 2016 (seulement). (Plus d'informations sur les étapes ici .) Et les fonctions du générateur étaient dans ES2015. Le PO a spécifiquement demandé d’éviter les intermédiaires et, bien que le générateur ne l’évite pas complètement, il fait un meilleur travail que celui ci-dessous ou (légèrement) Object.enties
.
FWIW, en utilisant Object.entries
:
[name, value]
à transmettre à new Map
Map
appelle une fonction du tableau pour obtenir un itérateur. le tableau crée et retourne un objet interator de tableau.Map
utilise cet objet itérateur pour obtenir les entrées (les tableaux [name, value]
) et construire la carte.En utilisant le générateur:
Map
appelle une fonction sur cet objet générateur pour en obtenir un itérateur; l'objet générateur renvoie lui-mêmeMap
utilise l'objet générateur (en tant qu'itérateur) pour obtenir les entrées (les tableaux [name, value]
) et construire la carte.Donc: Un intermédiaire de moins (le tableau de Object.entries
).
Cependant, utiliser Object.entries
est plus simple et créer ce tableau n’est pas un problème 99,999% du temps. Alors vraiment, l'un ou l'autre. Mais ils sont tous deux meilleurs que ceux ci-dessous. :-)
Réponse originale:
Pour initialiser une Map
, vous pouvez utiliser n'importe quel itérateur qui renvoie des paires clé/valeur sous forme de tableaux, tels qu'un tableau de tableaux:
const map = new Map([
['foo', 'bar']
]);
Il n'y a pas de conversion intégrée d'objet en mappage, mais cela se fait facilement avec Object.keys
:
const map = new Map();
let obj = {foo: 'bar'};
Object.keys(obj).forEach(key => {
map.set(key, obj[key]);
});
Vous pouvez bien sûr vous attribuer une fonction de travailleur pour gérer cela:
function buildMap(obj) {
let map = new Map();
Object.keys(obj).forEach(key => {
map.set(key, obj[key]);
});
return map;
}
Ensuite
const map = buildMap({foo: 'bar'});
Ou voici une version plus l33t (est-ce encore une chose?):
function buildMap(obj) {
return Object.keys(obj).reduce((map, key) => map.set(key, obj[key]), new Map());
}
(Oui, Map#set
renvoie la référence à la carte. Certains diront qu'il s'agit d'un abus de reduce
.)
Ou nous pouvons vraiment aller au-dessus de l'obscurité:
const buildMap = o => Object.keys(o).reduce((m, k) => m.set(k, o[k]), new Map());
Non, je ne ferais jamais ça pour de vrai. :-)
Dois-je vraiment d'abord le convertir en un tableau de tableaux de paires clé-valeur?
Non, 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:
function* entries(obj) {
for (let key in obj)
yield [key, obj[key]];
}
const map = new Map(entries({foo: 'bar'}));
map.get('foo'); // 'bar'
La réponse de Nils décrit comment pour convertir des objets en cartes, ce que j'ai trouvé très utile. Cependant, le PO se demandait également où se trouvent ces informations dans la documentation MDN. Même s’il n’était peut-être pas présent lorsque la question a été posée à l’origine, elle se trouve maintenant sur la page MDN pour Object.entries () sous la rubrique Conversion d’un objet en carte qui indique:
Conversion d'un objet en carte
Le constructeur
new Map()
accepte une valeur itérable deentries
. AvecObject.entries
, vous pouvez facilement convertir deObject
àMap
:const obj = { foo: 'bar', baz: 42 }; const map = new Map(Object.entries(obj)); console.log(map); // Map { foo: "bar", baz: 42 }
const myMap = new Map(
Object
.keys(myObj)
.map(
key => [key, myObj[key]]
)
)
Sinon, vous pouvez utiliser la méthode lodash toPairs :
const _ = require('lodash');
const map = new Map(_.toPairs({foo: 'bar'}));
ES6
convertir un objet en carte:
const objToMap = (o) => new Map(Object.entries(o));
convertir la carte en objet:
const mapToObj = (m) => [...m].reduce( (o,v)=>{ o[v[0]] = v[1]; return o; },{} )
Remarque: la fonction mapToObj suppose que les clés de la carte sont des chaînes (sinon, elles échoueront)
Avec l’aide de JQuery,
const myMap = new Map();
$.each( obj, function( key, value ) {
myMap[key] = value;
});