13. Listas
Vamos a repasar como se trabajan con las listas y profundizar con las funciones de Orden Superior.
Para entender como acceder a los elementos de una lista, vuelve a la lección de funciones y revisa las funciones
car,cdr,first,second,rest, etc.
Para crear una lista, puedes usar la función list o la notación de comillas:
* (list 1 2 3)
(1 2 3)
(A B C)
* (list 'a 'b 'c)
(A B C)
* (list "Hola" "Mundo")
("Hola" "Mundo")
* '(1 2 3)
(1 2 3)
* '(A B C)
(A B C)
* '("Hola" "Mundo")
("Hola" "Mundo")
Ahora vamos a trabajar con funciones de orden superior diseñadas para operar sobre secuencias (listas, vectores, etc.).
Una función de orden superior es aquella que puede tomar otras funciones como argumentos o devolver funciones como resultado. No modifican la secuencia original, sino que devuelven una nueva secuencia con los resultados. Son fundamentales en la programación funcional y permiten manipular colecciones de datos de manera más declarativa.
Filtrado
Filtrar elementos implica seleccionar solo aquellos que cumplen con una condición específica, definida por una condición.
remove-if/ remove-if-not
Filtra elementos de una secuencia según un predicado.
;; Elimina los elementos pares
* (remove-if #'evenp '(1 2 3 4 5 6))
(1 3 5)
find-if / find-if-not
Devuelve el primer elemento que cumple (o no cumple) con una condición. Devolverá la misma cantidad, o menos, de la secuencia original.
* (find-if #'evenp '(1 2 3 4 5 6))
2
* (find-if-not #'evenp '(1 2 3 4 5 6))
1
Mapeo
Te permite transformar cada elemento de una secuencia aplicando una función a cada uno de ellos. En otros lenguajes siempre te darán la misma cantidad de elementos que la secuencia original, en Common Lisp depende de la función que apliques.
mapcar
Aplica una función a cada elemento de una secuencia y devuelve una nueva lista con los resultados.
;; Eleva al cuadrado cada número
* (mapcar 'list (lambda (x) (* x x)) '(1 2 3 4 5))
(1 4 9 16 25)
mapcan
Aplica una función a cada elemento de una secuencia y concatena los resultados en una sola lista. Devolverá una lista de igual longitud o superior.
;; Para cada número, devuelve una lista con el número y su cuadrado
* (mapcan (lambda (x) (list x (* x x))) '(1 2 3))
(1 1 2 4 3 9)
Es una función interesante porque filtra y transforma, como si usaras a la vez un remove-if y un mapcar en un solo paso. Por ejemplo, la podría utilizar para aplanar una lista.
* (mapcan (lambda (x) (if (listp x) x (list x))) '(1 (2 3) (4 5) 6))
(1 2 3 4 5 6)
Para ampliar una lista.
* (mapcan (lambda (x) (list x "-")) '("Hello" "World"))
("Hello" "-" "World" "-")
O tanto filtrar como transformar a la vez.
* (mapcan (lambda (word) (when word (list (format nil "~a~a" "#" word)))) '("lisp" "clojure" nil "racket" nil))
("#lisp" "#clojure" "#racket")
maplist
Es una función peculiar. En lugar de recorrer cada elemento de la lista, recibes la lista completa en cada iteración pero con un elemento menos cada vez. Se elimina el primer elemento, hasta que la lista queda vacía.
* (maplist #'(lambda (x) x) '('a 'b 'c 'd 'e))
(('A 'B 'C 'D 'E) ('B 'C 'D 'E) ('C 'D 'E) ('D 'E) ('E))
* (maplist #'(lambda (x) (length x)) '('a 'b 'c 'd 'e))
(5 4 3 2 1)
Lo puedes utilizar para asuntos de ordenación, comparación de listas, o para generar combinaciones de elementos donde necesites "mirar hacia adelante" en la lista (por ejemplo, para comparar cada elemento con el siguiente).
Reducción
reduce
Combina los elementos de una lista en un solo valor.
Por ejemplo, para sumar todos los números de una lista:
(reduce #'+ '(1 2 3 4))
O siendo más explícito:
* (reduce #'(lambda (accumulator item)
(+ accumulator item)) '(1 2 3 4 5) :initial-value 0)
15
accumulatores el valor acumulado hasta el momento.itemes el elemento actual de la lista que se está procesando.:initial-valuees el valor inicial del acumulador. En este caso, comenzamos con0para la suma.
Predicados sobre secuencias
every
- some
- notary/notevery
Ordenamiento
- sort
- stable-sort
Aplicación
- funcall
- apply
Otras funciones útiles
position-if
count-if
member-if
Las que posiblemente usarás en tu día a día serán
reduce,mapcar,remove-ifysort.
This work is under a Attribution-NonCommercial-NoDerivatives 4.0 International license.
Desafíos de programación atemporales y multiparadigmáticos
Te encuentras ante un librillo de actividades, divididas en 2 niveles de dificultad. Te enfrentarás a los casos más comunes que te puedes encontrar en pruebas técnicas o aprender conceptos elementales de programación.
Buy the book
Support me on Ko-fi
Comments
There are no comments yet.