O que é um map?
Tags: braziliandevs, elixir, map, rocketseat
Published: 2021-03-26 03:07:16

Em outras linguagens de programação, como Ruby, conhecemos a estrutura de dados abaixo como Hash, em JavaScript a mesma estrutura de dados é chamada de objeto, já em python é chamada de dicionário.

```ruby
data = {name: "Diego", last_name: "Novais", age: 33}
data.class
> Hash
```

Em **Elixir** nós chamamos de **Map** e a forma como codificamos é um pouco diferente:

Utilizando ``%{...}`` e dentro dessa estrutura é adicionado pares de chave e valor ``key => value``.

```elixir
data = %{"name" => "Diego", :last_name => "Novais", 33 => "age"}
```

---

## Aprofundando um pouco mais...
Em Elixir, **Map** é implementado em **hash tree (árvores de hash)**, diferente de outras linguagens que é implementado usando **hash table (tabela de hash)**.

> Pode ser que em alguma tecnologia que você use também seja em **hash tree**, ou até mesmo de outra forma e eu adoraria saber, fique a vontade para dizer nos comentários =D.

**Map** foi implementado com **hash tree** por ser mais eficiente em relação à memória em linguagens funcionais com estruturas de dados imutáveis.

Dessa forma uma pesquisa por ``chave`` passa a ter um desempenho ``O(log (n))``. 

> O desempenho de ``O(log (n))``, sendo logarítmico, ainda é muito bom, e é apenas um pouco pior do que O(1), mesmo quando a quantidade de dados é enorme. Dê uma olhada no [cheatsheet do Big O](https://www.bigocheatsheet.com/) para obter uma boa visualização das diferenças relativas.
>
> -- <cite>https://inquisitivedeveloper.com/lwm-elixir-47/</cite>

---

## É importante saber que...

- As **Chaves e valores** em um **Map**, não seguem a ordem em que codificamos.

```elixir
iex> data = %{"name" => "Diego", :last_name => "Novais", 33 => "age"}
%{33 => "age", :last_name => "Novais", "name" => "Diego"}
```
<br/>

- Os **Maps** não impõem nenhuma restrição ao tipo de chave, qualquer coisa pode ser uma chave em um mapa.

```elixir
%{"string" => "Value", :atom => "Other value", 33 => "A integer"}
```
<br/>

- Como uma estrutura de **chave-valor**, os **Maps** não permitem chaves duplicadas. As chaves são comparadas usando o operador de igualdade exata ``(=== / 2)``.
<br/>

- Quando a chave em um par de **key-value** é um ``:atom``, a **sintaxe abreviada (shorthand syntax)** ``key: value`` pode ser usada:

```elixir
%{name: "Diego", last_name: "Novais", age: 33}
```
<br/>

- Os itens no **Map** podem ser acessados:
 - Funções do módulo **Map**: ``Map.get/3`` ou ``Map.fetch/2``.
 
```elixir
 iex> data = %{name: "Diego", last_name: "Novais", age: 33}
 %{name: "Diego", last_name: "Novais", age: 33}

 # Usando o Map.fetch/2
 iex> Map.fetch(data, :name)
 {:ok, "Diego"}
 
 # Usando o Map.get/3
 iex> Map.get(data, :name)
 "Diego"

 iex> Map.get(data, :year, 1987)
 1987
 ```
  - Através da [sintaxe de acesso](https://hexdocs.pm/elixir/Access.html) ``map[]``:

```elixir
 iex> data = %{name: "Diego", last_name: "Novais", age: 33}
 %{name: "Diego", last_name: "Novais", age: 33}

 iex> data[:name]
 "Diego"
 ```
 - Quando a chave for um ``:atom``, o elemento pode ser acessado através da notação ``map.key``

```elixir
 iex> data = %{name: "Diego", last_name: "Novais", age: 33}
 %{name: "Diego", last_name: "Novais", age: 33}

 iex> data.name
 "Diego"
 ```
 > **Obs.:** não adicione parênteses ao acessar campos ``data.key()``. Pois o Elixir irá considerar como uma chamada de função nos dados.

- Caso precise, por exemplo, manipular, pesquisar, deletar o Map e/ou algum de seus elementos, o próprio módulo **Map** possui várias funções que podem ser úteis, e você pode consultar na [documentação do Elixir](https://hexdocs.pm/elixir/Map.html#functions) que é bastante completa, por isso não irei entrar em cada função neste primeiro artigo sobre **Map**.

> Caso fique alguma dúvida, pode entrar em contato que irei te ajudar.

## Conclusão
Um **Map** é análogo ao **hash** em ``ruby``, ao **objeto** em ``JS`` e ao **dicionário** em python (apenas uma referência à linguagens de programação que eu conheço, e reforçando, pode ser que você tenha outra(s) referência(s) e eu adoraria saber, fique a vontade para dizer nos comentários =D).

No **Elixir**, temos vários detalhes sobre o **Map** que precisamos entender e meu objetivo foi trazer os principais pontos de uma forma mais didática possível. Espero que faça sentido para você e te ajude de alguma forma.