Cuando trabajamos con listas en Elixir, es fundamental conocer las herramientas que nos permiten manipularlas de forma eficiente y clara. Empezamos recordando que, para construir listas, podemos usar el operador de la barrita |, que nos permite añadir un elemento al principio de una lista existente. Por ejemplo, si tenemos la lista [1, 2, 3, 4] y queremos añadir el número 5 al inicio, simplemente escribimos:
lista = [5 | [1, 2, 3, 4]]
# Resultado: [5, 1, 2, 3, 4]
Este operador es muy útil para construir listas de manera sencilla y rápida.
Para concatenar listas, Elixir nos ofrece el operador ++. Este operador une dos listas en una sola, colocando los elementos de la primera lista antes que los de la segunda. Por ejemplo:
lista1 = [1, 2, 3]
lista2 = [4, 5]
lista_concatenada = lista1 ++ lista2
# Resultado: [1, 2, 3, 4, 5]
Es importante no confundir este operador con el de concatenación de cadenas, que en Elixir es el rombo <>. Aunque ambos sirven para unir, funcionan de manera diferente y aplican a tipos distintos.
Por otro lado, para eliminar elementos de una lista, podemos usar el operador --. Este operador elimina de la lista de la izquierda todos los elementos que aparecen en la lista de la derecha. Por ejemplo:
lista = [1, 2, 3, 4]
lista_filtrada = lista -- [2, 3]
# Resultado: [1, 4]
Aunque este operador funciona como una diferencia de conjuntos, debemos recordar que las listas en Elixir pueden contener duplicados, por lo que no es exactamente una operación de conjuntos.
Cuando queremos acceder a elementos en posiciones específicas dentro de una lista, podemos usar pattern matching para extraer la cabeza y la cola. Por ejemplo, para obtener el primer elemento:
[primero | _] = [1, 2, 3]
# primero = 1
Si queremos el segundo elemento, podemos hacer:
[_, segundo | _] = [1, 2, 3]
# segundo = 2
Y así sucesivamente, aunque esto se vuelve poco práctico para posiciones más alejadas.
Para acceder a un elemento en una posición arbitraria sin usar pattern matching, Elixir nos ofrece la función Enum.at/2. Esta función recibe una lista y un índice, y devuelve el elemento en esa posición, contando desde cero. Por ejemplo:
lista = ["a", "b", "c", "d"]
elemento = Enum.at(lista, 2)
# elemento = "c"
Aunque Enum.at/2 es muy útil, debemos tener en cuenta que no es la operación más eficiente para listas, ya que internamente recorre la lista hasta llegar al índice deseado. Esto se debe a que las listas en Elixir están diseñadas para operaciones en la cabeza, no para accesos aleatorios.
Para manipular listas de forma más avanzada, contamos con el módulo List, que ofrece funciones específicas para trabajar con listas. Por ejemplo, List.first/1 y List.last/1 nos permiten obtener el primer y último elemento de una lista respectivamente:
lista = [1, 2, 3, 4]
primero = List.first(lista)
# primero = 1
ultimo = List.last(lista)
# ultimo = 4
Si queremos insertar un elemento en una posición específica dentro de una lista, podemos usar List.insert_at/3. Esta función recibe la lista, la posición donde queremos insertar y el elemento a insertar. Por ejemplo:
lista = ["a", "b", "c"]
nueva_lista = List.insert_at(lista, 1, "hola")
# nueva_lista = ["a", "hola", "b", "c"]
Aquí, el índice 1 indica que insertamos hola antes del elemento que estaba en esa posición.
Para eliminar un elemento en una posición concreta, sin importar su valor, usamos List.delete_at/2. Por ejemplo, para eliminar el elemento en la posición 1:
lista = ["a", "b", "c"]
lista_modificada = List.delete_at(lista, 1)
# lista_modificada = ["a", "c"]
Esto es diferente a usar el operador --, que elimina elementos por valor, no por posición.
También podemos reemplazar un elemento en una posición específica con List.replace_at/3. Por ejemplo:
lista = ["a", "b", "c"]
lista_reemplazada = List.replace_at(lista, 1, "hola")
# lista_reemplazada = ["a", "hola", "c"]
Finalmente, para conocer la longitud de una lista, Elixir nos ofrece la función length/1, que está disponible en el kernel y es muy utilizada para obtener el número de elementos de una lista, ya sea vacía o no:
lista = [1, 2, 3, 4]
longitud = length(lista)
# longitud = 4
Con estas herramientas, podemos manipular listas en Elixir de manera flexible, desde construirlas y concatenarlas, hasta acceder, insertar, eliminar y reemplazar elementos en posiciones específicas, así como conocer su tamaño. Aunque algunas operaciones no son las más eficientes debido a la naturaleza de las listas, conocer estas funciones nos permite escribir código claro y funcional para la mayoría de los casos.