common-lisp
Хэш-таблицы
Поиск…
Создание хеш-таблицы
Хэш-таблицы создаются с помощью make-hash-table
:
(defvar *my-table* (make-hash-table))
Функция может принимать параметры ключевых слов для дальнейшего определения поведения полученной хеш-таблицы:
-
test
: выбор функции, используемой для сравнения ключей для равенства. Может быть, обозначение для одной из функцийeq
,eql
,equal
илиequalp
. По умолчанию используетсяeq
. -
size
: подсказка к реализации о пространстве, которое изначально может потребоваться. -
rehash-size
: Если целое число (> = 1), то при выполнении переименования хэш-таблица увеличит свою емкость на указанное число. Если в противном случае float (> 1.0), то хеш-таблица увеличит его емкость до продуктаrehash-size
и предыдущей емкости. -
rehash-threshold
: Указывает, как должна быть заполнена хэш-таблица, чтобы вызвать повторный перехват.
Итерация по элементам хэш-таблицы с помощью maphash
(defun print-entry (key value)
(format t "~A => ~A~%" key value))
(maphash #'print-entry *my-table*) ;; => NIL
Использование maphash
позволяет перебирать записи хэш-таблицы. Порядок итераций не указан. Первый аргумент - это функция, принимающая два параметра: ключ и значение текущей записи.
maphash
всегда возвращает NIL
.
Итерация по элементам хэш-таблицы с циклом
Макрос цикла поддерживает итерацию по ключам, значениям или ключам и значениям хэш-таблицы. Следующие примеры показывают возможности, но полный синтаксис цикла позволяет больше комбинаций и вариантов.
По ключам и значениям
(let ((ht (make-hash-table)))
(setf (gethash 'a ht) 1
(gethash 'b ht) 2)
(loop for k being each hash-key of ht
using (hash-value v)
collect (cons k v)))
;;=> ((A . 1) (B . 2))
(let ((ht (make-hash-table)))
(setf (gethash 'a ht) 1
(gethash 'b ht) 2)
(loop for v being each hash-value of ht
using (hash-key k)
collect (cons k v)))
;;=> ((A . 1) (B . 2))
По клавишам
(let ((ht (make-hash-table)))
(setf (gethash 'a ht) 1
(gethash 'b ht) 2)
(loop for k being each hash-key of ht
collect k))
;;=> (A B)
За значения
(let ((ht (make-hash-table)))
(setf (gethash 'a ht) 1
(gethash 'b ht) 2)
(loop for v being each hash-value of ht
collect v))
;;=> (1 2)
Итерация по элементам хэш-таблицы с помощью итератора хеш-таблицы
Ключи и значения хеш-таблицы можно повторить с помощью макроса с-хэш-таблицей-итератором . Это может быть немного сложнее, чем maphash или loop , но его можно использовать для реализации итерационных конструкций, используемых в этих методах. with-hash-table-iterator принимает имя и хэш-таблицу и связывает имя внутри тела, так что последовательные вызовы имени приводят к нескольким значениям: (i) логическое значение, указывающее, присутствует ли значение; (ii) ключ входа; и (iii) значение записи.
(let ((ht (make-hash-table)))
(setf (gethash 'a ht) 1
(gethash 'b ht) 2)
(with-hash-table-iterator (iterator ht)
(print (multiple-value-list (iterator)))
(print (multiple-value-list (iterator)))
(print (multiple-value-list (iterator)))))
;; (T A 1)
;; (T B 2)
;; (NIL)