List não é array!
Tags: braziliandevs, elixir, list, programming
Published: 2021-03-12 15:47:08

Quando eu vi o código abaixo pela primeira vez, logo pensei que provavelmente a variável **list** estaria recebendo um ``array``, pode ser que você também tenha pensado assim rsrs...

```Elixir
# Criando uma lista
list = [1, :atom, 3, 4, "string"]
```

Em Elixir é diferente, pois nesse caso **list** na verdade está recebendo uma ``List``.

## O que é uma List?

Em poucas palavras, uma List é uma lista ligada (linked list). 

Mas para entender melhor vamos precisar relembrar o que é um Array e em seguida falar com mais detalhes sobre List.

## Vamos falar um pouco sobre Array:

Um Array é uma coleção de dados de um mesmo tipo. 

No array podemos acessar o seu conteúdo por meio do índice. Ou seja, quando precisamos por exemplo acessar diretamente o terceiro elemento de um array, uma das formas de se fazer isso em Ruby seria passar o ``index`` 2: 

```Ruby
> x = [1, 2, 3, 4]
[1, 2, 3, 4]

> x[2]
3
```

Outra característica do array é que conseguimos iterar o array elemento por elemento diretamente. Em Ruby seria assim:

```Ruby
> x.each{|elemento| puts elemento}
1
2
3
4
```

## Agora, falando sobre List (lista ligada) e Elixir...

No Elixir ``List`` são listas encadeadas, ou seja, cada elemento está encadeado (ligado) ao próximo elemento através de posições na memória.

![Alt List](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fyuz3ju25b26jvuejg48.png)

Em uma ``List`` conseguimos acessar diretamente seu primeiro elemento (**Head (cabeça)**) e o restante dos elementos (**Tail (cauda)**).

```Elixir
> # Criando uma lista
> list = [1, :atom, 3, 4, "string"]
[1, :atom, 3, 4, "string"]

> # Retorna o primeiro elemento - Head (Cabeça)
> hd(list)
1

> # Retorna o restante dos elementos - Tail (Cauda)
> tl(list)
[:atom, 3, 4, "string"]
```

No exemplo acima, para acessar o primeiro elemento usamos a função de kernel do Elixir ``hd(list)``e para acessar o restante (cauda) da lista encadeada usamos a função de kernel do Elixir ``tl(list)``.

Também é possível acessar o ``head`` e ``tail`` de uma ``list`` usando **pattern matching**:

```Elixir
# Criando uma lista
> list = [1, :atom, 3, 4, "string"]
[1, :atom, 3, 4, "string"]

# Usando pattern matching para atribuir o primeiro elemento ao head
# e o restante da lista para o tail
> [head | tail] = list
[1, :atom, 3, 4, "string"]

# Retornando o primeiro elemento da lista
> head
1

# Retornando o restante da lista
> tail
[:atom, 3, 4, "string"]
```

Para percorrer cada elemento de uma ``list``usamos recursividade:

```Elixir
# Criando um módulo como exemplo
defmodule Example do
  def show_each_one([head | tail]) do
    # Função de Kernel IO para mostrar o primeiro elemento da lista elemento (head)
    IO.puts(head)
    
    # Fazendo a chamada para a própria função (onde acontece a recursão) para
    # passando o restante da lista
    show_each_one(tail)
  end
  
  # Criando uma função com pattern Matching
  # Caso seja passado uma lista vazia, irá retornar nulo (nil)
  def show_each_one([]), do: nil
end

# Criando uma lista
list = [1, :atom, 3, 4, "string"]
[1, :atom, 3, 4, "string"]


# Vamos chamar a função do nosso módulo criado
Example.show_each_one(list)

# Será retornado o seguinte resultado:
1
atom
3
4
string
nil
```

Podemos usar várias outras funções de kernel do Elixir para facilitar nosso trabalho com uma ``list``:
- ``first(list)`` que traz o primeiro elemento da lista.
- ``last(list)`` que traz o ultimo elemento
- ``insert_at(list, index, value)`` que permite inserir um elemento na lista em uma determinada posição.
- E várias outras.

Caso você precise saber mais detalhes sobre List eu sugiro que dê uma olhada na [documentação do Elixir](https://hexdocs.pm/elixir/List.html) que é bastante completa e tem vários exemplos.

Algo interessante que precisamos saber, é que as funções que usamos para se trabalhar com uma List usam recursão em sua implementação.

### Conclusão

De fato uma List não é um Array, e tem bastante diferença. Até mesmo na forma como usamos e pensamos sobre.

Contato:
Email: contato@diegonovais.com.br
LinkedIn: https://www.linkedin.com/in/diegonovais/
Github: https://github.com/dnovais