Arrays


Los arrays son estructuras de datos que sirven para almacenar vectores y matrices. Las listas también se pueden utilizar para el mismo fin, pero el acceso a los elementos es más rápido en el caso de los arrays. La ventaja de las listas es que son más flexibles para almacenar y transformar estructuras complejas de información.

make-array

;; Define un vector de cinco elementos 
(make-array 5 :initial-contents '(10 20 30 40 50))
#(10 20 30 40 50)
;; Define una matriz 2x3
(make-array '(2 3) :initial-contents
  '((3 6 1) (6 9 3)))
#2A((3 6 1) (6 9 3))
;; Matriz tridimensional 3x2x3
(make-array '(3 2 3) :initial-contents
  '(((1 2 3) (x y z))
    ((a b c) (6 7 8))
    ((1 3 3) (g h j))))
#3A(((1 2 3) (X Y Z)) ((A B C) (6 7 8)) ((1 3 3) (G H J)))
;; Matriz constante
(make-array '(2 2) :initial-element 7)
#2A((7 7) (7 7))
;; Matriz sin especificar elementos
(make-array '(2 3))
#2A((0 0 0) (0 0 0))
;; Matriz para decimales de precisión simple
(make-array '(2 3) :element-type 'single-float)
#2A((0.0 0.0 0.0) (0.0 0.0 0.0))
;; Matriz para decimales de doble simple
(make-array '(2 3) :element-type 'double-float)
#2A((0.0d0 0.0d0 0.0d0) (0.0d0 0.0d0 0.0d0))
(make-array 4 :initial-element 7e0
              :element-type 'single-float)
#(7.0 7.0 7.0 7.0)
(make-array 4 :initial-element 7.0
              :element-type 'single-float)
#(7.0 7.0 7.0 7.0)
(make-array 4 :initial-element 7d0
              :element-type 'double-float)
#(7.0d0 7.0d0 7.0d0 7.0d0)
;; Matriz para caracteres
(make-array '(2 3) :element-type 'character)
#2A((#\Nul #\Nul #\Nul) (#\Nul #\Nul #\Nul))
;; Construye array de texto sin 
;; conocer a priori su longitud
(let ( (str (make-array 0 
                :element-type 'character 
                :adjustable t 
                :fill-pointer 0)) )
  (format str "Hola")
  (format str ", ")
  (format str "mundillo")
  (format str "!")
  str )
"Hola, mundillo!"
;; Los arrays desplazados apuntan al contenido de otros arrays.
;; Al modificar el primer array, alteramos el desplazado.
(let (a b)
  ; construye matriz 2x2
  (setf a (make-array '(2 2) :initial-contents '((1 2) (3 4))))
  (print a)

  ; construye vector que apunta a la posición 1 de a
  (setf b (make-array 2 :displaced-to a
                        :displaced-index-offset 1))
  (print b)

  ; modificamos a y vemos b
  (setf (aref a 1 0) 'x)
  (print b)

  'hecho )
#2A((1 2) (3 4)) 
#(2 3) 
#(2 X) 
HECHO

aref

;; Define un vector y extrae el segundo elemento.
;; Los elementos empiezan a contar a partir de cero
(let ((v (make-array 5 :initial-contents '(10 20 30 40 50))))
  (aref v 1) )
20
;; Define un vector y cambia valor del segundo elemento.
(let ((v (make-array 5 :initial-contents '(10 20 30 40 50))))
  (setf (aref v 1) 999)
  v )
#(10 999 30 40 50)
;; Define matriz y cambia el elemento (2,2).
(let ((m (make-array '(2 3) :initial-contents '((3 6 1) (6 9 3)))))
  (setf (aref m 1 1) 999)
  m )
#2A((3 6 1) (6 999 3))
;; Suma dos matrices.
(let ((m1 (make-array '(2 2) :initial-contents '((3 6) (6 9))))
      (m2 (make-array '(2 2) :initial-contents '((5 8) (-8 1))))
      (s  (make-array '(2 2))) )
  (loop for i from 0 to 1 do
    (loop for j from 0 to 1 do
      (setf (aref s i j) (+ (aref m1 i j)
                            (aref m2 i j)))))
  s )
#2A((8 14) (-2 10))

array-dimension, array-dimensions, array-dimension-limit

;; Dimensiones del array
(let ((m (make-array '(2 3) :initial-contents
                     '((3 6 1) (6 9 3)))))
  (array-dimensions m))
(2 3)
;; Dimensiones del vector
(let ((v (make-array 3 :initial-contents
                     '(3 6 1) )))
  (array-dimensions v))
(3)
;; Dimensión de uno de los ejes
(let ((m (make-array '(2 3) :initial-contents
                     '((3 6 1) (6 9 3)))))
  (array-dimension m 0))
2
;; Número máximo de elementos de un array
array-dimension-limit
4611686018427387901

array-displacement

;; En un array desplazado, muestra el array original
;; y la posición a la que apunta 
(let (a b)
  ; construye vector
  (setf a (make-array 3 :initial-contents '(a b c)))

  ; construye vector que apunta a la posición 1 de a
  (setf b (make-array 2 :displaced-to a
                        :displaced-index-offset 1))
  (print (format nil "vector b: ~a" b))

  (array-displacement b) )
"vector b: #(B C)" 
#(A B C)
1

array-element-type

;; Devuelve el tipo declarado de datos
(let (a)
  (setf a (make-array 2 :element-type 'double-float))
  (array-element-type a))
DOUBLE-FLOAT

array-in-bounds-p

;; Indica si los índices están o no dentro de rango
(let (a)
  (setf a (make-array '(3 4)))
  (list (array-in-bounds-p a 2 2)
        (array-in-bounds-p a 3 3) ))
(T NIL)

array-rank, array-rank-limit

;; Devuelve el rango de un array 
(let (a)
  (setf a (make-array '(3 4 5 2) :initial-element 1))
  (array-rank a) )
4
;; Máximo rango admisible 
array-rank-limit
65529

array-total-size, array-total-size-limit

;; Número total de elementos de un rango
(let (a)
  (setf a (make-array '(3 4 5 2) :initial-element 1))
  (array-total-size a) )
120
;; Máximo número de elementos de una array
array-total-size-limit
4611686018427387901

arrayp

;; Es o no un array
(mapcar 'arrayp
  (list 3 #c(1 1) (make-array 1) "Abur" 'Hola #\c))
(NIL NIL T T NIL NIL)

length

;; Número de elementos de un vector
(let ((m (make-array 3 :initial-contents
                     '(3 6 1) )))
  (length m))
3

adjust-array

;; Cambia dimensiones de un array
(let ((m (make-array '(3 2) :initial-element 7)))

  ; dimensiones iniciales
  (print (array-dimensions m))

  ; ajusta a nuevas dimensiones
  (setf m (adjust-array m '(4 4)))

  ; comprobamos
  (print (array-dimensions m))
  'hecho)
(3 2) 
(4 4) 
HECHO
;; Cambio en el contenido tras el ajuste de la dimensión
(let ((m (make-array '(3 2) :initial-element 7)))

  ; dimensiones iniciales
  (print m)

  ; ajusta a nuevas dimensiones
  (setf m (adjust-array m '(2 4) :initial-element 1))

  ; comprobamos
  (print m)
  'hecho)
#2A((7 7) (7 7) (7 7)) 
#2A((7 7 1 1) (7 7 1 1)) 
HECHO

fill-pointer

; Devuelve la posición de la siguiente entrada
(let (a)
  (setf a (make-array 5 :initial-contents '(a b c d e)
                        :fill-pointer 3))
  (print (format nil "Número de dimensiones del array: ~a"
                     (array-dimensions a)))
  (print (format nil "Estado actual del array: ~a" a))
  (print (format nil "Número de elementos actuales en el array: ~a"
                     (length a)))
  (print (format nil "Posición siguiente entrada: ~a"
                     (fill-pointer a)))
  'fin )
"Número de dimensiones del array: (5)" 
"Estado actual del array: #(A B C)" 
"Número de elementos actuales en el array: 3" 
"Posición siguiente entrada: 3" 
FIN
; Cambia la posición de la siguiente entrada
(let (a)
  (setf a (make-array 5 :initial-contents '(a b c d e)
                        :fill-pointer 3))
  (print (format nil "Estado actual del array: ~a" a))
  (print (format nil "Posición para la siguiente entrada: ~a"
                     (fill-pointer a)))
  ; nueva posición de entrada
  (setf (fill-pointer a) 2)
  (print (format nil "Estado actual del array: ~a" a))
  'fin )
"Estado actual del array: #(A B C)" 
"Posición para la siguiente entrada: 3" 
"Estado actual del array: #(A B)" 
FIN

vector-pop, vector-push

;; Extrae elemento cuya posición es la que indica
;; el puntero de relleno.
(let (a)
  (setf a (make-array 5 :initial-contents '(a b c d e)
                        :fill-pointer 3))
  (print (format nil "Estado actual del array: ~a" a))
  (vector-pop a)
  (print (format nil "Posición para la siguiente entrada: ~a" a))
  'fin )
"Estado actual del array: #(A B C)" 
"Posición para la siguiente entrada: #(A B)" 
FIN
;; Añade elemento en la posición que indica
;; el puntero de relleno.
(let (a)
  (setf a (make-array 5 :initial-element 1
                        :fill-pointer 3))
  (print (format nil "Estado original del array: ~a" a))
  (vector-push 4 a)
  (print (format nil "Añado un elemento: ~a" a))
  'fin )
"Estado original del array: #(1 1 1)" 
"Añado un elemento: #(1 1 1 4)" 
FIN
;; 
(let (a)
  (setf a (make-array 5 :initial-element 1
                        :fill-pointer 4))
  (print (format nil "Estado original del array: ~a" a))
  (setf (fill-pointer a) 2)
  (vector-push 3 a)
  (print (format nil "Añado un elemento: ~a" a))
  'fin )
"Estado original del array: #(1 1 1 1)" 
"Añado un elemento: #(1 1 3)" 
FIN

© 2016, TecnoStats