`Objeto Map`
Este artigo explica o objeto Map.
Vamos explicar passo a passo, desde operações básicas até exemplos práticos úteis em cenários do mundo real.
YouTube Video
Objeto Map
Map é uma coleção que armazena pares de chave-valor. É semelhante a um objeto, mas difere porque qualquer tipo, como objetos, funções ou primitivos, pode ser usado como chave, e a ordem de inserção é preservada.
Noções básicas sobre Map
Primeiro, vamos ver como criar um Map e realizar operações básicas.
O código a seguir é um exemplo mínimo que cria um mapa vazio, adiciona chaves e recupera valores.
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
- Nesse código, você pode adicionar elementos com
set, recuperar valores comgete verificar o número de elementos comsize. Mapmantém a ordem de inserção, tornando-o adequado para processamentos que dependem da ordem.
Comportamento de set, get, has e delete
Aqui estão exemplos de operações típicas de leitura, escrita, verificação de existência e exclusão.
Com o código a seguir, você pode verificar os valores de retorno e os efeitos de cada método.
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 }
getretornaundefinedse a chave não existir.hasverifica a existência de uma chave, edeleteremove uma chave.- Além disso, como
setretorna o próprio map, é possível encadear métodos.
Qualquer tipo pode ser usado como chave (utilizando objetos como chaves)
Uma das principais vantagens do Map é que você pode usar objetos diretamente como chaves.
O exemplo a seguir mostra como associar valores em um Map utilizando objetos como chaves.
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'
- Ao usar objetos como chaves, é importante que eles sejam a mesma referência. Mesmo que seus conteúdos sejam iguais, objetos com referências diferentes são tratados como distintos e não são a mesma chave.
Iteração (laço)
Map preserva a ordem de inserção, por isso a iteração é frequentemente utilizada.
A seguir, mostramos como usar for...of, forEach e os métodos keys(), values() e 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()retorna um array de pares[chave, valor], que pode ser convertido em um array usando a sintaxe spread. Observe que o callback paraforEachrecebe argumentos na ordemvalor, chave.
Convertendo entre Map e Object
Você pode converter um objeto existente em um Map, ou converter um Map para um objeto simples ou para um array.
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]]
- O uso de
Object.entrieseObject.fromEntriesfacilita a conversão. No entanto, como as chaves de objetos são limitadas a strings ou símbolos, chaves que não são strings são perdidas ao converter de volta para um objeto.
Padrão prático: Contagem de frequência (Count Map)
Ao contar a frequência de elementos em um array, usar um Map simplifica o processo.
O código a seguir é um exemplo de uso de um map para contar a frequência de strings em um array e ordená-las.
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]]
- Usar um
Mappermite verificar a existência e atualizar facilmente. Isso pode ser feito com objetos também, masMappode ser mais intuitivo ao trabalhar com chaves arbitrárias.
Observações sobre Map e JSON.stringify (Serialização)
JSON.stringify não pode serializar um Map diretamente. Se você precisa salvar um Map, primeiro deve convertê-lo.
O exemplo a seguir mostra como converter um Map em um array antes de transformá-lo em JSON, e como restaurá-lo.
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
- Maps que precisam ser salvos ou transmitidos devem ser convertidos em arrays antes da serialização. Ao restaurar, use
JSON.parsepara converter em um array e depois transforme de volta em umMap.
Introdução ao WeakMap e como utilizá-lo
WeakMap se diferencia por suas chaves serem fracamente referenciadas (sujeitas à coleta de lixo).
É útil para manter cache ou metadados com objetos como chaves, liberando-os automaticamente quando o objeto chave é coletado.
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
WeakMapnão pode ser enumerado nem ter seu tamanho verificado, mas é útil para evitar vazamentos de memória.
Resumo
Map é uma coleção conveniente que, ao contrário dos objetos, permite qualquer tipo como chave e preserva a ordem de inserção. Ao entender tudo, das operações básicas ao uso avançado, você pode gerenciar dados de forma mais flexível e intuitiva. Usando Object e Map de forma adequada para o caso de uso, você pode melhorar muito a clareza e legibilidade do código.
Você pode acompanhar o artigo acima usando o Visual Studio Code em nosso canal do YouTube. Por favor, confira também o canal do YouTube.