En Common Lisp, como en otros lenguajes, un array, o arreglo, es un conjunto de elementos a los que se accede mediante índices enteros. Los tipos de los elementos pueden ser heterogéneos. El array puede ser multidimensional (no solo unidimensional).
make-array permite crear arrays.
Tiene muchas opciones, pero sus formas más simples permiten crear arrays N-dimensionales con todos los elementos inicializados a un mismo valor, o con el array inicializado a los valores de otra secuencia (como una lista).
Su primer argumento es una lista con el tamaño de cada dimensión.
(make-array '(4) :initial-element 3) ; => #(3 3 3 3)
(make-array '(2 2) :initial-element 'x) ; => #2A((X X) (X X))
(make-array '(3 3 3)
:initial-contents '(((a b c) (d e f) (g h i))
((j k l) (m n o) (p q r))
((s t u) (v w x) (y z &))))
; => #3A(((A B C) (D E F) (G H I))
((J K L) (M N O) (P Q R))
((S T U) (V W X) (Y Z &)))
(Fíjate cómo los arrays N-dimensionales se imprimen con el número de dimensiones.)
Los arrays también se pueden crear usando el mismo formato con el que se imprimen:
#(x y z) ; => #(X Y Z)
#2A((1 2) (3 4)) ; => #2A((1 2) (3 4))
Para acceder a los elementos de un vector usa aref; los índices empiezan en cero.
La cantidad de índices que proporciones debe coincidir con el rango del array.
(aref #2A((1 2 3) (3 4 5)) 1 0) ; => 3
(aref #3A(((a b) (c d))
((e f) (g h))
((t u) (v w)))
2 0 1) ; => U
(aref #2A((1) (2)) 0) ; => ERROR (because not enough indexes provided)
Además, los índices que proporciones deben estar «dentro de los límites» según las dimensiones que se dieron cuando se creó el array.
Esto se puede comprobar con array-in-bounds-p:
(array-in-bounds-p #2A((1) (2)) 0 0) ; => T
(array-in-bounds-p #2A((1) (2)) 2 0) ; => NIL
También se puede acceder a un elemento con row-major-aref, que toma un solo número entero que especifica el elemento en el orden row-major.
(El índice row-major se puede calcular a partir de los índices con array-row-major-index.)
(array-row-major-index #2A((1 2 3) (4 5 6)) 1 1 ) ; => 4
(row-major-aref #2A((1 2 3) (4 5 6)) 4) ; => 5
Para determinar si un objeto es un array puedes usar arrayp.
(arrayp #(1 2 3)) ; => T
(arrayp #2((1 2 3) (4 5 6))) ; => T
(arrayp (list 1 2 3)) ; => NIL
Puedes obtener información diversa sobre un array con las siguientes funciones:
array-rank para obtener el número de dimensiones del array (lo que se conoce como el rango del array).array-dimensions para obtener una lista con los tamaños de las dimensiones del array.array-dimension para obtener el tamaño de una de las dimensiones.array-total-size para obtener la cantidad total de elementos del array.(let ((array #3A(((0 1) (2 3) (4 5))
((6 7) (8 9) (A B))
((C D) (E F) (G H))
((I J) (K L) (M N)))))
(list (array-rank array)
(array-dimensions array)
(array-dimension array 1)
(array-total-size array))) ; => (3 (4 3 2) 2 24)
El estándar de Common Lisp define algunos límites sobre el tamaño máximo de los arrays. Estos límites están disponibles en algunas constantes definidas:
array-rank-limit: la cantidad máxima permitida de dimensiones de un array (definida como no menor que 8).array-dimension-limit: el tamaño máximo de una dimensión cualquiera (definido como no menor que 1024).array-total-size-limit: la cantidad máxima de elementos de un array cualquiera (definida como no menor que 1024).