Desmistificando Listas e Tuplas no Elixir

Dentre os tipos básicos do Elixir temos as Listas e as Tuplas. Na maioria das vezes o uso desses dois tipos acabam confundindo os iniciantes visto que em um primeiro momento parecem cumprir a mesma função. Bom, hoje a missão é desmistificá-los.

Vamos começar falando sobre a Lista/List.

A lista é definida de uma forma muito parecida com Arrays/Vetores em outras linguagens, veja algumas implementações válidas:

[1, 2, 3, 4]
[1, 2, "a", "b", 3.45]
["videos", "de", "TI", 2018]

A primeira coisa que podemos observar é que é possível construir listas com tipos de dados diferentes, mas as semelhanças com Arrays param por aí, visto que antes de mais nada não é possível acessar uma posição indexada como em um Array tradicional.

Por definição, uma lista no Elixir nada mais é do que uma “lista encadeada”, então, para você que nunca estudou sobre estrutura de dados, vou explicar rapidamente do que se trata.

Variáveis

Bom, para entender o que é uma lista encadeada, precisamos dar um passo para trás e entender sobre variáveis que, de forma bem resumida, são “espaços” reservados na memória do computador onde podemos dar um nome e armazenar um valor.

Veja a figura abaixo, por exemplo. Temos uma variável “N1” onde foi armazenado o valor 32. E temos também a variável “S1” onde armazenamos o valor “Jackson”.

Perceba que ambas também possuem um “endereço de memória” que é fixo, FFF1B FFF1D, respectivamente. Ou seja, toda variável fica em uma posição aleatória da memória e possui uma identificação fixa. Para facilitar, podemos chamar o local onde a variável foi definida de “célula de memória”, ou seja, no exemplo acima foram usadas 2 células de memória, ok?

Listas

Agora que já sabemos como as variáveis se comportam na memória do computador, imagine se a própria variável puder indicar qual o endereço de memória da próxima variável/célula de memória?

Pois bem, isso é o que chamamos de “lista encadeada” ou “linked list” quando estamos estudando estrutura de dados.

No exemplo acima temos o endereço de memória FFF1A armazenando o valor/string “videos” e informando que a próxima célula de memória a ser acessada é a FFF3A, que por sua vez armazena o valor/string “de” e informa que a próxima célula de memória a ser acessada é a FFF6A, que por sua vez armazena o valor/string “ti” e informa que a próxima célula de memória a ser acessada é a FFF5A, que por sua vez armazena o valor/inteiro 2018 e não informa outra célula de memória, finalizando assim a lista.

Todo esse “encadeamento” entre as posições de memória é o que forma a nossa Lista no Elixir.

Isolando só a lista, é normal que tenhamos figuras como essa abaixo para representá-la de forma genérica.

A figura acima representa as células de memória armazenando algum valor e indicando a próxima célula.

Nesse tipo de estrutura temos duas definições importantes, são elas: A cabeçae a cauda da lista.

Olhando a figura abaixo podemos dizer que a primeira célula, que contém o valor 5, é a cabeça (head) todo o restante da lista é a cauda (tail).

Nesse momento acredito que você já percebeu que existe uma enorme diferença entre um Array e uma Lista encadeada, e ter esse entendimento é de suma importância no aprendizado da linguagem Elixir.

Agora está fácil entender o motivo pelo qual é impossível acessar uma posição específica da lista sem ter que percorrê-la, não é mesmo?

Devido a isso temos duas importantes funções que sempre são usadas quando estamos trabalhando com Listas, são elas hd/1 e tl/1 (implementadas no Kernel), que significam head e tail respectivamente. Veja como elas funcionam.

minha_lista = ["videos", "de", "TI", 2018]
hd(minha_lista)
#=> "videos"
tl(minha_lista)
#=> ["de", "TI", 2018]

Conforme visto acima, a função hd/1 devolve a cabeça da lista, já tl/1devolve a cauda.

Além dessas funções temos muitas outras específicas para se trabalhar com listas e elas podem ser encontradas no módulo List da documentação oficial.

Tuplas

Agora vamos falar um pouco sobre tuplas. Podemos começar definindo uma tupla. Vejamos:

{1, 2, 3, 4}
{1, 2, "a", "b", 3.45}
{"videos", "de", "ti", 2018}

Assim como as listas, podemos construir tuplas com tipos de dados diferentes, mas, diferentemente das listas, as tuplas são armazenadas continuamente na memória, deixando-as muito parecidas com Arrays em outras linguagens.

Perceba que na imagem acima cada um dos valores foi armazenado em uma célula de memória, uma seguida da outra.

Dessa forma, é possível acessar os valores de forma indexada através da função elem/2 (implementada no Kernel). Vejamos um exemplo.

minha_tupla = {"videos", "de", "ti", 2018}
elem(minha_tupla, 2)
#=> "TI"

Além da função elem/2, existem diversas outras que podem facilitar o uso das tuplas e você pode conhecê-las na documentação oficial.

É isso, gente! Espero que tenham aprendido um pouco mais o sobre esses dois tipos básicos do Elixir.

Como sempre, não esqueçam de deixar seus comentários, nos seguir nas redes sociais e também se cadastrar em nossa newsletter semanal.