Em Common Lisp, como em outras linguagens, um array (vetor) é um conjunto de elementos acessados por índices inteiros. Os tipos dos elementos podem ser heterogêneos. O array pode ser multidimensional (não apenas unidimensional).
make-array permite criar arrays.
Ele tem muitas opções, mas suas formas mais simples permitem criar arrays N-dimensionais com todos os elementos inicializados com um único valor, ou com o array inicializado com os valores de outra sequência (como uma lista).
Seu primeiro argumento é uma lista com o tamanho de cada dimensão.
(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 &)))
(Repare como os arrays N-dimensionais são impressos com o número de dimensões.)
Arrays também podem ser criados usando o mesmo formato em que são impressos:
#(x y z) ; => #(X Y Z)
#2A((1 2) (3 4)) ; => #2A((1 2) (3 4))
Para acessar elementos de um vetor use aref; os índices começam em zero.
O número de índices fornecidos deve corresponder ao número de dimensões (rank) do 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)
Além disso, os índices fornecidos devem estar 'dentro dos limites' considerando as dimensões fornecidas quando o array foi criado.
Isso pode ser verificado com array-in-bounds-p:
(array-in-bounds-p #2A((1) (2)) 0 0) ; => T
(array-in-bounds-p #2A((1) (2)) 2 0) ; => NIL
Um elemento também pode ser acessado com row-major-aref, que recebe um único inteiro especificando o elemento em ordem row-major.
(O índice row-major pode ser calculado a partir dos índices via 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 se um objeto é um array, pode-se usar arrayp.
(arrayp #(1 2 3)) ; => T
(arrayp #2((1 2 3) (4 5 6))) ; => T
(arrayp (list 1 2 3)) ; => NIL
Várias informações sobre um array podem ser obtidas com as seguintes funções:
array-rank para obter o número de dimensões do array (chamado de rank do array).array-dimensions para obter uma lista com os tamanhos das dimensões do array.array-dimension para obter o tamanho de uma das dimensões.array-total-size para obter o número total de elementos do 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)
O padrão Common Lisp define alguns limites para o tamanho máximo dos arrays. Esses limites estão disponíveis em algumas constantes definidas:
array-rank-limit: o número máximo permitido de dimensões de um array (definido como não menor que 8).array-dimension-limit: o tamanho máximo de qualquer dimensão (definido como não menor que 1024).array-total-size-limit: o número máximo de elementos de qualquer array (definido como não menor que 1024).