Lección 5: Secuencias | Curso de Emacs Lisp

Lección 5: Secuencias

Los string, listas y arrays son considerados secuencias.

Secuencias

(sequencep '(1 2 3 4 5)) ;; t
(sequencep '()) ;; t
(sequencep [1 2 3 4 5]) ;; t
(sequencep []) ;; t
(sequencep "12345") ;; t
(sequencep "") ;; t
(sequencep ?a) ;; nil
(sequencep 1.2) ;; nil
(sequencep nil) ;; t

;; length
(length '(1 2 3 4 5)) ;; 5
(length '()) ;; 0
(length "12345") ;; 5
(length nil) ;; 0

;; elt
(elt '(1 2 3 4 5) 0) ;; 1
(elt "Hello" 0) ;; ?72
(elt '(1 2 3 4 5) -1) ;; error -out of range

Strings

Los strings se consideran un array de carácteres.

"Hola Emacs!"

"Hola \
Emacs!"
(make-string 4 ?a) ;; aaaa
(string ?H ?o ?l ?a) ;; Hola

Predicates

(stringp "Emacs") ;; t
(stringp 1) ;; nil
(stringp nil) ;; nil

(string-or-null-p "Emacs") ;; t
(string-or-null-p 1) ;; nil
(string-or-null-p nil) ;; t

(char-or-string-p "Emacs") ;; t
(char-or-string-p ?a) ;; t
(char-or-string-p "a") ;; t
(char-or-string-p 1) ;; nil
(char-or-string-p nil) ;; nil

(arrayp "Emacs") ;; t
(sequencep "Emacs") ;; t
(listp "Emacs") ;; nil

Comparaciones

;; Compacaciones de string

;; string= is equal to string-equal

(string= "hola" "hola") ;; t
(string= "hola" "HOLA") ;; nil
(string= "hola" "hola mundo") ;; nil

;; string< is equal to string-lessp

(string< "a" "b") ;; t
(string< "b" "a") ;; nil
(string< "a" "a") ;; nil

;; string> is equal to string-greaterp

(string> "a" "b") ;; nil
(string> "b" "a") ;; t
(string> "a" "a") ;; nil

Operaciones

(substring "Emacs" 0 3) ;; "Emac"
(substring "Emacs" 1) ;; "macs"
(substring "Emacs" 0) ;; "Emacs"

(concat "abc" "def") ;; "abcdef"
(concat "abc" "def" "ghi") ;; "abcdefghi"

;; Default separator is [ \f\t\n\r\v]+
(split-string "abc def ghi") ;; ("abc" "def" "ghi")

;; Separator is specified by the second argument
(split-string "abc,def,ghi," ",") ;; ("abc" "def" "ghi" "")
(split-string "abc,def,ghi," "," t) ;; ("abc" "def" "ghi")

Formateo

Crear strings desde valores existentes

(format "Hola %s" "Pepe") ;; "Hola Pepe"
(format "Los ganadores son %s" '(1 2 3)) ;; "Los ganadores son (1 2 3)"
(format "Hoy cumplo %d años" 30) ;; "Hoy cumplo 30 años"
(format "El valor de PI es %f" 3.141592) ;; "El valor de PI es 3.141592"
(format "El valor de PI es %0.2f" 3.141592) ;; "El valor de PI es 3.14"
(format "Mañana compraré %d %s" 2 "manzanas") ;; "Mañana compraré 2 manzanas"

Escribiendo mensajes

Puedes escribir mensajes en el echo area (minibuffer) y *Messages* buffer usuando la función message.

(message "Bienvenido a Emacs")

Usa el mismo sistema de formateo que format.

(message "Bienvenido a %s" "Emacs")

Listas

Una lista en Elisp es una secuencia ordenada de elementos, donde cada elemento puede ser cualquier tipo de dato, incluyendo otras listas.

(1 "hola" 3.14)

A continuación puede ser un ejemplo donde se anidan otras listas.

(1 (2 3) (4 5 6) 7)

Su estructura es enlazada. Ello quiere decir que posee una cabeza, que puede ser obtenida con car.

(car '(1 2 3 4)) ;; 1

Y una cola, que sería el resto de los elementos. Se puede obtener con cdr.

(cdr '(1 2 3 4)) ;; (2 3 4)

Cons Cells

Son una listas encadenadas. Piensa en eslabones de una cadena, cada cons sería un eslabón. Si quieres construir una cadena debes ir encadenando diferentes eslabones dentro de otros.

Por ejemplo:

(cons 1 2) ;; (1 . 2)

O usando .:

'(1 . 2) ;; (1 . 2)

Leer

Se representa como una lista de dos elementos, el primero es el valor del primer eslabón y el segundo es el valor del segundo eslabón. Se separan por un punto.

Si quiero obtener el primer elemento de la lista, puedo usar car:

(car (cons 1 2)) ;; 1

Si quiero obtener el segundo elemento de la lista, puedo usar cdr:

(cdr (cons 1 2)) ;; 2

Modificar

Para modificar el primer elemento de la lista, puedo usar setcar:

(setq mi-lista (cons 1 2)) ;; (1 . 2)
(setcar mi-lista 3)
mi-lista ;; (3 . 2)

Para modificar el segundo elemento de la lista, puedo usar setcdr:

(setq mi-lista (cons 1 2)) ;; (1 . 2)
(setcdr mi-lista 3)
mi-lista ;; (1 . 3)

Crear

Cuando busquemos construir listas de listas encadenadas, podemos usar cons para ir encadenando eslabones.

Por ejemplo:

(cons 1 (cons 2 (cons 3 (cons 4 (cons 5 nil))))) ;; (1 2 3 4 5)

O también:

(cons 1 '(2 3 4 5)) ;; (1 2 3 4 5)

Utilizaremos append para concatenar listas:

(append '(1 2 3) '(4 5 6)) ;; (1 2 3 4 5 6)
(append '(1 2 3) '(4)) ;; (1 2 3 4)

Predicates

(listp (cons 1 2)) ;; t
(listp '(1 . 2)) ;; t
(listp 1) ;; nil

(listp nil) ;; t
(listp '()) ;; t

(listp (cons 1 2)) ;; t
(listp '(1 2 3)) ;; t
(consp (cons 1 2)) ;; t
(consp '(1 2 3)) ;; t

Alists

Son listas de pares de elementos, similar a con cons pairs, donde el primer elemento es la clave y el segundo el valor.

(setq ganadores '((oro . "Hercules") (plata . "Marcos") (bronce . "Pedro")))

Para acceder a los elementos usando la clave se usa la función alist-get, que recibe como parámetros la clave y como segundo la alist.

(alist-get 'oro ganadores) ;; "Hercules"
(alist-get 'plata ganadores) ;; "Marcos"
(alist-get 'bronce ganadores) ;; "Pedro"

Podemos usar assq para obtener el par de la clave.

(assq 'oro ganadores) ;; (oro . "Hercules")

O rassq para obtener el par por su valor.

(rassq "Hercules" ganadores) ;; (oro . "Hercules")

Plists

Son listas de pares de elementos, similar a Alist, salvo que todos los elementos se guardan en una lista plana alternando entre claves y valores.

;; '(clave valor clave valor clave valor)
(setq ganadores '(oro "Hercules" plata "Marcos" bronce "Pedro"))

Leer

Puedo utilizar plist-get para recuperar un elemento por su clave.

(plist-get ganadores 'plata) ;; "Marcos"

Añadir

Para ello disponemos de plist-put.

(plist-put ganadores 'platino "Juan")
;; '(oro "Hercules" plata "Marcos" bronce "Pedro" platino "Juan")

Modificar

Podemos volver a utilizar plist-put.

(setq ganadores '(oro "Hercules" plata "Marcos" bronce "Pedro"))
(plist-put ganadores 'oro "No hay")
(plist-get ganadores 'oro)
;; "No hay"

Arrays

Son secuencias de valores que están continuos en memoria. Su mayor ventaja es que son muy rápidos de leer ya que los valores están seguidos. Los Strings son Arrays.

(setq un-array-de-paises ["Argentina" "Bolivia" "Brasil" "Chile" "Colombia" "Ecuador" "España" "Guyana" "Paraguay" "Peru" "Surinam" "Uruguay" "Venezuela"])

Leer

Para obtener un elemento de un array por su índice debes usar aref.

(aref un-array-de-paises 0) ; "Argentina"

Su longitud nos lo devuelve length.

(length un-array-de-paises) ; 13

Para conseguir el último elemento de un Array podemos usar el siguiente truco.

(aref un-array-de-paises (1- (length un-array-de-paises))) ; "Venezuela"

En caso de buscar una sublista, disponemos de subseq.

(subseq un-array-de-paises 0 3) ; ["Argentina" "Bolivia" "Brasil"]

Modificar

Disponemos de aset para el cometido.

(aset un-array-de-paises 3 "Costa Rica") ; "Costa Rica"

Añadir

aset permite agregar un elemento a un Array.

(aset un-array-de-paises (length un-array-de-paises) "México") ; "México"

Eliminar

De nuevo, podemos usar aset, salvo que indicaremos un nil como valor.

(aset un-array-de-paises 3 nil) ; nil

Equivalencias con String

Podemos realizar las mismas acciones usando un String porque en Emacs un String es un array de caracteres.

(setq un-string "Hispanos")
(aref un-string 0) ; "H"
(length un-string) ; 8
(aref un-string (1- (length un-string))) ; "s"
(subseq un-string 0 3) ; "His"
(aset un-string 3 "a") ; "a"

Esta obra está bajo una Licencia Creative Commons Atribución-NoComercial-SinDerivadas 4.0 Internacional.

Atribución/Reconocimiento-NoComercial-SinDerivados 4.0 Internacional

¿Me invitas a un café? ☕

Puedes hacerlo usando el terminal.

ssh customer@andros.dev -p 5555

Comentarios

{{ comments.length }} comentarios

Nuevo comentario

Nueva replica  {{ formatEllipsisAuthor(replyComment.author) }}

Acepto la política de Protección de Datos.

Escribe el primer comentario