Objet `Map`

Cet article explique l'objet Map.

Nous expliquerons étape par étape, des opérations de base jusqu'aux exemples pratiques utiles dans des situations réelles.

YouTube Video

Objet Map

Map est une collection qui stocke des paires clé-valeur. C'est similaire à un objet, mais il diffère en ce que tout type, comme les objets, les fonctions ou les types primitifs, peut être utilisé comme clé, et l'ordre d'insertion est préservé.

Bases de Map

Voyons d'abord comment créer un Map et effectuer des opérations de base.

Le code suivant est un exemple minimal qui crée une carte vide, ajoute des clés et récupère des valeurs.

1// Create an empty Map and add key-value pairs
2const m = new Map();
3m.set('a', 1);
4m.set('b', 2);
5
6console.log(m.get('a')); // 1
7console.log(m.size);     // 2
  • Avec ce code, vous pouvez ajouter des éléments avec set, récupérer des valeurs avec get et vérifier le nombre d'éléments avec size.
  • Map conserve l'ordre d'insertion, ce qui le rend adapté aux traitements dépendants de l'ordre.

Comportement de set, get, has et delete

Voici des exemples d'opérations courantes de lecture, d'écriture, de vérification d'existence et de suppression.

Avec le code suivant, vous pouvez vérifier les valeurs de retour et l'effet de chaque méthode.

 1// Demonstrate set, get, has, and delete
 2const m2 = new Map();
 3m2.set('x', 10);
 4console.log(m2.has('x'));  // true
 5console.log(m2.get('y'));  // undefined
 6
 7m2.delete('x');
 8console.log(m2.has('x'));  // false
 9
10// set returns the map itself, allowing method chaining
11m2.set('a', 1).set('b', 2);
12console.log(m2);  // Map { 'a' => 1, 'b' => 2 }
  • get renvoie undefined si la clé n'existe pas. has vérifie l'existence d'une clé, et delete supprime une clé.
  • Également, comme set renvoie la map elle-même, l'enchaînement de méthodes est possible.

Tout type peut être utilisé comme clé (utilisation d'objets comme clés)

L'un des principaux avantages de Map est que vous pouvez utiliser des objets directement comme clés.

L'exemple suivant montre comment associer des valeurs dans un Map en utilisant des objets comme clés.

 1// Use objects as keys in a Map
 2const keyObj = { id: 1 };
 3const keyFunc = () => {};
 4const objMap = new Map();
 5
 6// Another object with the same content but a different reference
 7const anotherKeyObj = { id: 1 };
 8
 9objMap.set(keyObj, 'objectValue');
10objMap.set(keyFunc, 'functionValue');
11objMap.set(anotherKeyObj, 'anotherValue');
12
13console.log(objMap.get(keyObj));         // 'objectValue'
14console.log(objMap.get(keyFunc));        // 'functionValue'
15console.log(objMap.get(anotherKeyObj));  // 'anotherValue'
  • Lorsque l'on utilise des objets comme clés, il est important qu'ils soient la même référence. Même si leur contenu est identique, des objets avec des références différentes sont traités comme distincts et ne sont pas la même clé.

Itération (boucles)

Map conserve l'ordre d'insertion, donc l'itération est souvent utilisée.

Ci-dessous, nous montrons comment utiliser for...of, forEach et les méthodes keys(), values() et entries().

 1// Iterating a Map with for...of and forEach
 2const iterMap = new Map([['a', 1], ['b', 2], ['c', 3]]);
 3
 4// for...of over entries (default)
 5for (const [key, value] of iterMap) {
 6  console.log(key, value);
 7}
 8
 9// forEach callback
10iterMap.forEach((value, key) => {
11  console.log(key, value);
12});
13
14// keys() and values()
15console.log([...iterMap.keys()]);   // ['a','b','c']
16console.log([...iterMap.values()]); // [1,2,3]
  • entries() renvoie un tableau de paires [clé, valeur], qui peut être transformé en tableau à l'aide de l'opérateur de propagation. Notez que le callback de forEach reçoit les arguments dans l'ordre valeur, clé.

Conversion entre Map et Object

Vous pouvez convertir un objet existant en Map, ou convertir un Map en objet simple ou en tableau.

 1// Convert between Map and Object / Array
 2const obj = { a: 1, b: 2 };
 3const mapFromObj = new Map(Object.entries(obj)); // Object -> Map
 4console.log(mapFromObj.get('a')); // 1
 5
 6const objFromMap = Object.fromEntries(mapFromObj); // Map -> Object
 7console.log(objFromMap); // { a: 1, b: 2 }
 8
 9const arrayFromMap = [...mapFromObj]; // Map -> Array of [key, value]
10console.log(arrayFromMap); // [['a',1], ['b',2]]
  • L'utilisation de Object.entries et Object.fromEntries facilite la conversion. Cependant, comme les clés des objets sont limitées aux chaînes de caractères ou aux symboles, les clés non textuelles sont perdues lors de la reconversion en objet.

Modèle pratique : Comptage de fréquence (Count Map)

Lorsqu'il s'agit de compter la fréquence des éléments dans un tableau, l'utilisation d'une Map simplifie le processus.

Le code suivant est un exemple d'utilisation d'une map pour compter les fréquences de chaînes dans un tableau et les trier.

1// Count frequencies with Map
2const arr = ['apple','banana','apple','orange','banana','apple'];
3const freq = new Map();
4
5for (const item of arr) {
6  freq.set(item, (freq.get(item) || 0) + 1);
7}
8
9console.log([...freq.entries()]); // [['apple',3], ['banana',2], ['orange',1]]
  • L'utilisation d'un Map permet des vérifications d'existence et des mises à jour faciles. Cela peut également être fait avec des objets, mais Map peut être plus intuitif lorsqu'on travaille avec des clés arbitraires.

Remarques sur Map et JSON.stringify (Sérialisation)

JSON.stringify ne peut pas sérialiser un Map directement. Si vous devez enregistrer un Map, vous devez d'abord le convertir.

L'exemple suivant montre comment convertir une Map en tableau avant de la transformer en JSON, et comment la restaurer.

1// Serialize and deserialize a Map
2const m3 = new Map([['x', 1], ['y', 2]]);
3const json = JSON.stringify([...m3]); // convert to array first
4console.log(json); // '[["x",1],["y",2]]'
5
6const restored = new Map(JSON.parse(json));
7console.log(restored.get('x')); // 1
  • Les Maps qui doivent être sauvegardées ou transmises doivent être converties en tableaux avant la sérialisation. Lors de la restauration, utilisez JSON.parse pour convertir en tableau, puis retransformez-les en Map.

Introduction à WeakMap et son utilisation

WeakMap diffère en ce que ses clés sont faiblement référencées (soumis au ramasse-miettes).

Il est utile pour conserver du cache ou des métadonnées avec des objets comme clés, qui sont automatiquement libérés lorsque l'objet clé est collecté.

1// WeakMap for metadata tied to object lifecycle
2const wm = new WeakMap();
3let obj = {};
4wm.set(obj, { meta: 'info' });
5console.log(wm.get(obj)); // { meta: 'info' }
6
7obj = null; // now the object can be GC'd and its entry removed from WeakMap
  • WeakMap ne peut ni être énuméré ni avoir sa taille vérifiée, mais il est utile pour éviter les fuites de mémoire.

Résumé

Map est une collection pratique qui, contrairement aux objets, permet tout type de clé et préserve l'ordre d'insertion. En comprenant tout, des opérations de base aux utilisations avancées, vous pouvez gérer les données de manière plus flexible et intuitive. En utilisant Object et Map de manière appropriée selon le cas d'utilisation, vous pouvez grandement améliorer la clarté et la lisibilité du code.

Vous pouvez suivre l'article ci-dessus avec Visual Studio Code sur notre chaîne YouTube. Veuillez également consulter la chaîne YouTube.

YouTube Video