Хеш-таблиці в Common Lisp - це структури даних для зберігання асоціативних даних. Вони зіставляють ключі (якими може бути будь-який обʼєкт) зі значеннями (якими може бути будь-який обʼєкт).
Хеш-таблиці можна створити за допомогою функції make-hash-table.
Функція make-hash-table приймає кілька ключових параметрів для тонкого налаштування початкового розміру хеш-таблиці та порогу її зміни розміру; повну інформацію про них можна знайти в документації.
Що важливіше, вона також приймає test ключовий параметр, який визначає, як порівнюються ключі під час вставляння, пошуку та вилучення ключів і значень.
Значенням аргументу test може бути одне з 'eq, 'eql, 'equal або 'equalp, які відповідають загальним предикатам рівності.
Типовим значенням є 'eql.
Щоб отримати значення за його ключем, ми використовуємо gethash.
gethash приймає [необовʼязковий аргумент][concept-defualt-arguments], який відіграє роль значення, що його буде повернуто, якщо ключа немає в хеш-таблиці.
gethash також повертає кілька значень (це пояснюється в іншій концепції).
Перше значення - це значення цього ключа в хеш-таблиці, типове значення, якщо його задано, або NIL.
Друге значення - булеве значення (англ. Boolean), яке вказує, чи був ключ присутній у хеш-таблиці, чи ні.
Щоб вставити пару ключ-значення, ми використовуємо setf разом із gethash.
Щоб вилучити ключ і його значення, використовуємо remhash.
Щоб вилучити всі ключі та значення, використовуємо clrhash
Хоча хеш-таблиця в Common Lisp, як і в інших мовах, не гарантує жодного порядку, іноді буває корисно перебрати її, обробивши кожну пару ключ-значення.
Це можна зробити за допомогою maphash:
(maphash #'(lambda (key value) (print (cons key value))) *hash-table*)
(Він виведе кожен ключ і значення як cons-пару, по одній у рядку.)
(setf *hash-table* (make-hash-table)) ; => #<HASH-TABLE :TEST EQL :COUNT 0 {100375FD23}>
(gethash :foo *hash-table*) ; => NIL
; NIL
(gethash :foo *hash-table*
:default-value) ; => :DEFAULT-VALUE
; NIL
(setf (gethash :foo *hash-table*) :bar) ; => :BAR
(gethash :foo *hash-table*) ; => :BAR
; T
(setf (gethash :key *hash-table*) :value) ; => :RIGHT
(gethash :key *hash-table*) ; => :VALUE
; T
(remhash :key *hash-table*) ; => T
(gethash :key *hash-table*) ; => NIL
; => NIL
(clrhash *hash-table*) ; => #<HASH-TABLE :TEST EQL :COUNT 0 {1005A90103}>
(gethash :foo *hash-table*) ; => NIL
; NIL