Elixir - listas e tuplas
Listas (vinculadas)
Uma lista encadeada é uma lista heterogênea de elementos que são armazenados em locais diferentes na memória e são controlados por meio de referências. Listas vinculadas são estruturas de dados usadas especialmente na programação funcional.
Elixir usa colchetes para especificar uma lista de valores. Os valores podem ser de qualquer tipo -
[1, 2, true, 3]
Quando Elixir vê uma lista de números ASCII imprimíveis, Elixir irá imprimir isso como uma lista de caracteres (literalmente uma lista de caracteres). Sempre que você vir um valor em IEx e não tiver certeza de qual é, você pode usar oi função para recuperar informações sobre ele.
IO.puts([104, 101, 108, 108, 111])
Os caracteres acima na lista podem ser impressos. Quando o programa acima é executado, ele produz o seguinte resultado -
hello
Você também pode definir listas ao contrário, usando aspas simples -
IO.puts(is_list('Hello'))
Quando o programa acima é executado, ele produz o seguinte resultado -
true
Tenha em mente que as representações entre aspas simples e aspas duplas não são equivalentes no Elixir, pois são representadas por tipos diferentes.
Comprimento de uma lista
Para encontrar o comprimento de uma lista, usamos a função de comprimento como no seguinte programa -
IO.puts(length([1, 2, :true, "str"]))
O programa acima gera o seguinte resultado -
4
Concatenação e Subtração
Duas listas podem ser concatenadas e subtraídas usando o ++ e --operadores. Considere o seguinte exemplo para entender as funções.
IO.puts([1, 2, 3] ++ [4, 5, 6])
IO.puts([1, true, 2, false, 3, true] -- [true, false])
Isso lhe dará uma string concatenada no primeiro caso e uma string subtraída no segundo. O programa acima gera o seguinte resultado -
[1, 2, 3, 4, 5, 6]
[1, 2, 3, true]
Cabeça e cauda de uma lista
A cabeça é o primeiro elemento de uma lista e a cauda é o resto de uma lista. Eles podem ser recuperados com as funçõeshd e tl. Vamos atribuir uma lista a uma variável e recuperar seu início e fim.
list = [1, 2, 3]
IO.puts(hd(list))
IO.puts(tl(list))
Isso nos dará o início e o fim da lista como saída. O programa acima gera o seguinte resultado -
1
[2, 3]
Note - Obter o início ou o fim de uma lista vazia é um erro.
Outras funções de lista
A biblioteca padrão Elixir fornece uma série de funções para lidar com listas. Vamos dar uma olhada em alguns deles aqui. Você pode verificar o resto aqui Lista .
S.no. | Nome e descrição da função |
---|---|
1 | delete(list, item) Exclui o item fornecido da lista. Retorna uma lista sem o item. Se o item ocorrer mais de uma vez na lista, apenas a primeira ocorrência será removida. |
2 | delete_at(list, index) Produz uma nova lista removendo o valor no índice especificado. Índices negativos indicam um deslocamento do final da lista. Se o índice estiver fora dos limites, a lista original será retornada. |
3 | first(list) Retorna o primeiro elemento da lista ou nulo se a lista estiver vazia. |
4 | flatten(list) Nivela a lista fornecida de listas aninhadas. |
5 | insert_at(list, index, value) Retorna uma lista com o valor inserido no índice especificado. Observe que o índice é limitado ao comprimento da lista. Índices negativos indicam um deslocamento do final da lista. |
6 | last(list) Retorna o último elemento da lista ou nulo se a lista estiver vazia. |
Tuplas
Tuplas também são estruturas de dados que armazenam várias outras estruturas dentro delas. Ao contrário das listas, eles armazenam elementos em um bloco contíguo de memória. Isso significa que acessar um elemento de tupla por índice ou obter o tamanho da tupla é uma operação rápida. Os índices começam do zero.
Elixir usa chaves para definir tuplas. Como listas, tuplas podem conter qualquer valor -
{:ok, "hello"}
Comprimento de uma tupla
Para obter o comprimento de uma tupla, use o tuple_size funcionar como no programa a seguir -
IO.puts(tuple_size({:ok, "hello"}))
O programa acima gera o seguinte resultado -
2
Anexando um valor
Para acrescentar um valor à tupla, use a função Tuple.append -
tuple = {:ok, "Hello"}
Tuple.append(tuple, :world)
Isso criará e retornará uma nova tupla: {: ok, "Hello",: world}
Inserindo um Valor
Para inserir um valor em uma determinada posição, podemos usar o Tuple.insert_at função ou o put_elemfunção. Considere o seguinte exemplo para entender o mesmo -
tuple = {:bar, :baz}
new_tuple_1 = Tuple.insert_at(tuple, 0, :foo)
new_tuple_2 = put_elem(tuple, 1, :foobar)
Notar que put_elem e insert_atretornou novas tuplas. A tupla original armazenada na variável tupla não foi modificada porque os tipos de dados Elixir são imutáveis. Por ser imutável, o código Elixir é mais fácil de raciocinar, pois você nunca precisa se preocupar se um código específico está alterando sua estrutura de dados no local.
Tuplas vs. Listas
Qual é a diferença entre listas e tuplas?
As listas são armazenadas na memória como listas vinculadas, o que significa que cada elemento em uma lista mantém seu valor e aponta para o seguinte elemento até que o final da lista seja alcançado. Chamamos cada par de valor e ponteiro de célula cons. Isso significa que acessar o comprimento de uma lista é uma operação linear: precisamos percorrer toda a lista para descobrir seu tamanho. Atualizar uma lista é rápido, desde que estejamos adicionando elementos.
Por outro lado, tuplas são armazenadas de forma contígua na memória. Isso significa que obter o tamanho da tupla ou acessar um elemento por índice é rápido. No entanto, atualizar ou adicionar elementos às tuplas é caro porque requer a cópia de toda a tupla na memória.