Estrutura de dados - Coleções chaveadas
Tags: javascript, webdev, braziliandevs, brasil
Published: 2023-03-22 00:56:44

Sabemos que todas as linguagens de programação tem estrutura de dados embutidas e que se diferem uma das outras. Meu objetivo aqui não vai ser explicar e mostrar o que são e como funcionam estrutura de dados em si, mas mostrar um tipo de estrutura de dados em Javascript que acredito que seja interessante conhecermos, por mais que no dia a dia quase sempre recorremos a outro tipo de estrutura de dados.

## Map
Na estrutura Map, temos conjuntos de chave e valor, e o mais interessante aqui é que podemos ter **qualquer tipo de valor** para identificar essas chaves e valores.

O conjunto de valores é iterado por ordem de inserção, e quando fazemos uma iteração nessa estrutura, usando um loop, for...of por exemplo, é **retornado um array de [chave, valor]** para cada iteração.

Aqui já podemos perceber que os objetos são praticamente iguais aos Maps, e sempre optamos por usar objetos. Mas vou te mostrar algumas diferenças entre eles:

### Tipos das chaves
As chaves do Map podem ser qualquer valor (incluindo funções, objetos, ou qualquer outro tipo primitivo). 
A chave de um Objeto deve ser uma String ou um Symbol.

### Iteração
Um Map é iterável, então ele pode ser diretamente iterável.
O Objeto não implementa o protocolo de iteração, e os objetos não podem ser iterados diretamente usando o for...of (por padrão).

### Performance
O Map performa melhor em cenários envolvendo adições e remoções frequentes em pares chave-valor.
Já o Objeto não é otimizado para adições e remoções frequentes de pares chave-valor.

## Definindo Maps

```javascript
const contacts = new Map()
contacts.set('Andrey', {email: 'andreyaraujo.dev@gmail.com'})
contacts.get('Andrey') 
// {email: 'andreyaraujo.dev@gmail.com'}
contacts.has('Araújo') // false
console.log(contacts.size) // 1
contacts.delete('Andrey') // true
```
É bastante simples usar Maps, mas temos que ter cuidados com alguns pontos ao definirmos Maps e seus valores:
```javascript
const contacts = new Map()
contacts['Andrey'] = {email: 'andreyaraujo.dev@gmail.com'}
```
Essa forma de definir propriedades não interage com a estrutura de dados do Map. Dessa forma é usada a implementação genérica do objeto. O valor 'Andrey' não é armazenado no Map para queries. Outras operações nos dados irão falhar.
```javascript
contacts.has('Andrey') // false
contacts.delete('Andrey') // false
```

## WeakMap
Da mesma forma que o Map, o WeakMap é um objeto com chave/valor, em que as chaves são fracamente referenciadas. Os valores podem ser de qualquer tipo, já as chaves tem que ser objetos.

A sua utilização é bem semelhante ao Map, mas podendo receber um Array ou outro objeto iterável cujos elementos são pares key-value.

```javascript
const wm = new WeakMap()
wm.set({ name: 'andrey' }, { phone: 99999 })
```

## Set
Objetos Set são coleções iteráveis, por ordem de inserção, que **aceitam qualquer tipo de valor, desde que não se repitam**. Na sua definição também podemos passar um objeto iterável, sem  valores repetidos, onde todos esses valores são adicionados ao novo Set. Caso esse objeto iterável contenha itens repetidos, o novo objeto não terá esses objetos repetidos.

```javascript
const mySet = new Set([1, 1, 2, 3]) // {1, 2, 3}
```

Comparando ao Array, o Set tem algumas facilidades, como busca, deleção de elementos, (.has, .delete) mas ainda tem funcionalidades bem básicas, o Array nos da muito mais opções como por exemplo, `.reduce, .sort, .filter`, etc.

**Mas e porque usar o Set ao invés de Array ou objeto normal?**
Como o Set contém apenas elementos distintos, deixa a vida muito mais fácil se soubermos antecipadamente que queremos evitar salvar dados duplicados em nossa estrutura.

## WeakSet
Assim como no objeto Set, o WaekSet permite armazenar valores únicos. Também pode receber como parâmetro um objeto iterável. A diferença aqui é que no WeakSet, **só podemos armazenar objetos**, e não qualquer tipo de valor igual no Set. Aqui também as referências ao objetos na coleção são mantidos fracamente.

## Conclusão
O Javascript nos da algumas opções para trabalhar com estrutura de dados, por mais que no dia a dia não sejam tão usadas, para cada caso elas tem sua utilidade e valor, cabe a nós analisar e ver onde cada uma se encaixa melhor.