Как и во многих языках в lisp есть только скалярные типы данных, но и коллекции. В этой статье рассмотрим строки, вектора, хэштаблицы и списки. Так же здесь будут описаны некоторые операции для обработки коллекций. Всем заинтересованным добро пожаловать под кат.
Символы
Начнём с символов. Символы это скалярный тип данных и задаются они так:
(defvar *char-example* #\x) (defvar *char-example-2* #\Space)
Как видно из примера просто спереди ставится решётка и слэш. Некоторые символы описываются не одним символом. Такая тавтология, но в примере всё видно. Для сравнения символов, как впрочем и других переменных используются операции сравнения. Укажу только некоторые из них:
(= #\a #\a) ;T (\= #\a #\A) ;nil
Вторая строка вернёт nil и это не ошибка, деле в том, что сравнение регистронезависимо, поэтому ниже таблица всех функций сравнения
Numeric Analog | Case-Sensitive | Case-Insensitive |
= | CHAR= | CHAR-EQUAL |
/= | CHAR/= | CHAR-NOT-EQUAL |
< | CHAR< | CHAR-LESSP |
> | CHAR> | CHAR-GREATERP |
<= | CHAR<= | CHAR-NOT-GREATERP |
>= | CHAR>= | CHAR-NOT-LESSP |
Строки
Строка это одномерный массив символов. Наверное, это самый простой элемент из коллекций lisp. Для строк действуют такие же принципы сравнения как и для символов, только вместо префикса CHAR будет префикс STRING. Особо говорить мне тут больше нечего, поэтому переходим к следующему типу.
Массивы или векторы
Массивы могут быть и многомерными. Описываются они так
(vector 1 2 3) ;#(1 2 3) (make-array count :initial-element el :fill-pointer :adjustable t :element-type 'character)
Для функции make-array не все параметры важны, некоторые можно и опускать. С помощью ключа adjustable можно задавать массивы изменяемого размера.
Вставить в массив или извлечь из него:
(vector-push 1 *vect*) (vector-pop *vect*) ;1 (vector-push 1 *vect*) (vector-push 2 *vect*) (vector-push 3 *vect*) (elt 1 *vect*) ;2 (aref 1 *vect*) ;2
Хэш-таблицы
Не буду описывать то как работают хэш-таблицы и что это такое. Думаю и так всё ясно. Сразу к коду:
(defvar *h* (make-hash-table)) (gethash 'foo *h*) ;nil (setf (gethash 'foo *h*) 'bar) (gethash 'foo *h*) ;BAR (remhash 'foo *h*)
Видно как обращаться к элементу хэш-таблицы и как его удалять. Однако, не понятно как пройтись по всем элементам хэш таблицы. А вот как:
(maphash #'(lambda (k v) (format t "Key: ~a, Value: ~a~%" k v)) *h*)