Списки ассоциаций
Список ассоциаций, или alist вкратце, записывает отображение ключей на значения. Это список ячеек cons, называемых ассоциациями: CAR каждой ячейки cons является ключом, а CDR — соответствующим значением.6
Вот пример alist. Ключ pine сопоставлен со значением cones; ключ oak сопоставлен со значением acorns; а ключ maple сопоставлен со значением seeds.
((pine . cones) (oak . acorns) (maple . seeds))
И значения, и ключи в alist могут быть любыми объектами Lisp. Например, в следующем alist символ a сопоставлен с числом 1, а строка "b" — со списком (2 3), который является CDR элемента alist:
((a . 1) ("b" 2 3))
Иногда лучше спроектировать alist так, чтобы сопоставленное значение хранилось в CAR CDR элемента. Вот пример такого alist:
((rose red) (lily white) (buttercup yellow))
Здесь мы рассматриваем red как значение, связанное с rose. Одно из преимуществ такого типа alist заключается в том, что вы можете хранить другую связанную информацию — даже список других элементов — в CDR CDR. Недостаток заключается в том, что вы не можете использовать rassq (см. ниже), чтобы найти элемент, содержащий данное значение. Когда ни один из этих соображений не важен, выбор является вопросом вкуса, до тех пор, пока вы сохраняете согласованность в отношении этого для любого данного alist.
Тот же самый alist, показанный выше, можно рассматривать как содержащий связанное значение в CDR элемента; значение, связанное с rose, было бы списком (red).
Списки ассоциаций часто используются для записи информации, которую вы могли бы иначе хранить в стеке, поскольку новые ассоциации могут быть легко добавлены в начало списка. При поиске в списке ассоциаций ассоциации с заданным ключом возвращается первая найденная, если их несколько.
В Emacs Lisp, это не ошибка, если элемент списка ассоциаций не является ячейкой cons. Функции поиска alist просто игнорируют такие элементы. Во многих других версиях Lisp в таких случаях генерируются ошибки.
Обратите внимание, что списки свойств похожи на списки ассоциаций по нескольким аспектам. Список свойств ведет себя как список ассоциаций, в котором каждый ключ может встречаться только один раз. См. Списки свойств для сравнения списков свойств и списков ассоциаций.
- Функция: assoc ключ alist &optional testfn
-
Эта функция возвращает первую ассоциацию для ключ в alist, сравнивая ключ с элементами alist, используя testfn, если это функция, и
equalв противном случае (см. Предикаты равенства). Если testfn является функцией, она вызывается с двумя аргументами: CAR элемента из alist и ключ. Функция возвращаетnil, если ни одна ассоциация в alist не имеет CAR, равного ключ в соответствии с testfn. Например:(setq trees '((pine . cones) (oak . acorns) (maple . seeds))) ⇒ ((pine . cones) (oak . acorns) (maple . seeds)) (assoc 'oak trees) ⇒ (oak . acorns) (cdr (assoc 'oak trees)) ⇒ acorns (assoc 'birch trees) ⇒ nilВот другой пример, в котором ключи и значения не являются символами:
(setq needles-per-cluster '((2 "Austrian Pine" "Red Pine") (3 "Pitch Pine") (5 "White Pine"))) (cdr (assoc 3 needles-per-cluster)) ⇒ ("Pitch Pine") (cdr (assoc 2 needles-per-cluster)) ⇒ ("Austrian Pine" "Red Pine")
Функция assoc-string очень похожа на assoc за исключением того, что она игнорирует некоторые различия между строками. См. Сравнение текстов.
- Функция: rassoc значение alist
-
Эта функция возвращает первую ассоциацию со значением значение в alist. Она возвращает
nil, если ни одна ассоциация в alist не имеет CDRequalзначение.rassocпохожа наassoc, за исключением того, что она сравнивает CDR каждой ассоциации alist вместо CAR. Вы можете рассматривать это как обратнуюassoc, нахождение ключа для данного значения.
- Функция: assq ключ alist
-
Эта функция похожа на
assocв том, что она возвращает первую ассоциацию для ключ в alist, но выполняет сравнение, используяeq.assqвозвращаетnil, если ни одна ассоциация в alist не имеет CAReqключ. Эта функция используется чаще, чемassoc, так какeqбыстрее, чемequal, и большинство alist используют символы в качестве ключей. См. Предикаты равенства.(setq trees '((pine . cones) (oak . acorns) (maple . seeds))) ⇒ ((pine . cones) (oak . acorns) (maple . seeds)) (assq 'pine trees) ⇒ (pine . cones)С другой стороны,
assqобычно не полезна в alist, где ключи могут быть не символами:(setq leaves '(("simple leaves" . oak) ("compound leaves" . horsechestnut))) (assq "simple leaves" leaves) ⇒ Unspecified; might benilor("simple leaves" . oak). (assoc "simple leaves" leaves) ⇒ ("simple leaves" . oak)
- Функция: alist-get ключ alist &optional default remove testfn
-
Эта функция похожа на
assq. Она находит первую ассоциацию(key . value), сравнивая ключ с элементами alist, и, если найдена, возвращает значение этой ассоциации. Если ассоциация не найдена, функция возвращает default. Сравнение ключ с элементами alist использует функцию, указанную в testfn, по умолчаниюeq.Это обобщенная переменная (см. Обобщенные переменные), которая может быть использована для изменения значения с
setf. При ее использовании для установки значения, необязательный аргумент remove не-nilозначает удаление ассоциации ключ из alist, если новое значение отличается отeqldefault.
- Функция: rassq значение alist
-
Эта функция возвращает первую ассоциацию со значением значение в alist. Она возвращает
nil, если ни одна ассоциация в alist не имеет CDReqзначение.rassqпохожа наassq, за исключением того, что она сравнивает CDR каждой ассоциации alist вместо CAR. Вы можете рассматривать это как обратнуюassq, нахождение ключа для данного значения.Например:
(setq trees '((pine . cones) (oak . acorns) (maple . seeds))) (rassq 'acorns trees) ⇒ (oak . acorns) (rassq 'spores trees) ⇒ nilrassqне может искать значение, сохранённое в CAR CDR элемента:(setq colors '((rose red) (lily white) (buttercup yellow))) (rassq 'white colors) ⇒ nilВ этом случае CDR ассоциации
(lily white)не является символомwhite, а списком(white). Это становится более понятным, если ассоциация записана в обозначении пар с точкой:(lily white) ≡ (lily . (white))
- Функция: assoc-default ключ alist &optional test default
-
Эта функция ищет в alist совпадение для ключ. Для каждого элемента alist она сравнивает элемент (если он атом) или CAR элемента (если он cons) с ключ, вызывая test с двумя аргументами: элементом или его CAR и ключ. Аргументы передаются в таком порядке, чтобы вы могли получить полезные результаты, используя
string-matchсо списком ассоциаций, который содержит регулярные выражения (см. Поиск с помощью регулярных выражений). Если test опущено илиnil, для сравнения используетсяequal.Если элемент alist соответствует ключ по этому критерию, то
assoc-defaultвозвращает значение, основанное на этом элементе. Если элемент является cons, то значением является CDR элемента. В противном случае возвращаемое значение — default.Если ни один элемент alist не соответствует ключ,
assoc-defaultвозвращаетnil.
- Функция: copy-alist alist
-
Эта функция возвращает двухступенчатую глубокую копию alist: она создает новую копию каждой ассоциации, так что вы можете изменять ассоциации нового alist, не изменяя старый.
(setq needles-per-cluster '((2 . ("Austrian Pine" "Red Pine")) (3 . ("Pitch Pine"))(5 . ("White Pine")))) ⇒ ((2 "Austrian Pine" "Red Pine") (3 "Pitch Pine") (5 "White Pine")) (setq copy (copy-alist needles-per-cluster)) ⇒ ((2 "Austrian Pine" "Red Pine") (3 "Pitch Pine") (5 "White Pine")) (eq needles-per-cluster copy) ⇒ nil (equal needles-per-cluster copy) ⇒ t (eq (car needles-per-cluster) (car copy)) ⇒ nil (cdr (car (cdr needles-per-cluster))) ⇒ ("Pitch Pine")(eq (cdr (car (cdr needles-per-cluster))) (cdr (car (cdr copy)))) ⇒ tЭтот пример показывает, как
copy-alistпозволяет изменить ассоциации одной копии без влияния на другую:(setcdr (assq 3 copy) '("Martian Vacuum Pine")) (cdr (assq 3 needles-per-cluster)) ⇒ ("Pitch Pine")
- Функция: assq-delete-all ключ alist
-
Эта функция удаляет из alist все элементы, чья CAR соответствует ключ, так же, как если бы вы использовали
delqдля удаления каждого такого элемента по одному. Она возвращает укороченный alist и часто изменяет исходную структуру списка alist. Для получения правильных результатов используйте возвращаемое значениеassq-delete-allвместо просмотра сохраненного значения alist.(setq alist (list '(foo 1) '(bar 2) '(foo 3) '(lose 4))) ⇒ ((foo 1) (bar 2) (foo 3) (lose 4)) (assq-delete-all 'foo alist) ⇒ ((bar 2) (lose 4)) alist ⇒ ((foo 1) (bar 2) (lose 4))
- Функция: assoc-delete-all ключ alist &optional test
Эта функция похожа на
assq-delete-all, за исключением того, что принимает необязательный аргумент test — предикатную функцию для сравнения ключей в alist. Если опущено илиnil, по умолчанию используетсяequal. Как иassq-delete-all, эта функция часто изменяет исходную структуру списка alist.
- Функция: rassq-delete-all значение alist
Эта функция удаляет из alist все элементы, чья CDR соответствует значение. Она возвращает укороченный alist и часто изменяет исходную структуру списка alist.
rassq-delete-allпохожа наassq-delete-all, за исключением того, что она сравнивает CDR каждой ассоциации alist вместо CAR.
- Макрос: let-alist alist body
-
Создаёт привязку для каждого символа, используемого в качестве ключей в списке ассоциаций alist, с префиксом точки. Это может быть полезно при доступе к нескольким элементам в одном и том же списке ассоциаций, и лучше всего понять его на простом примере:
(setq colors '((rose . red) (lily . white) (buttercup . yellow))) (let-alist colors (if (eq .rose 'red) .lily)) ⇒ whiteТело body проверяется во время компиляции, и только символы, которые появляются в body с символом «.» в качестве первого символа имени символа, будут привязаны. Поиск ключей выполняется с помощью
assq, аcdrзначения возвращаемого результата этойassqприсваивается в качестве значения для привязки.Вложенные списки ассоциаций поддерживаются:
(setq colors '((rose . red) (lily (belladonna . yellow) (brindisi . pink)))) (let-alist colors (if (eq .rose 'red) .lily.belladonna)) ⇒ yellowВложение
let-alistдруг в друга разрешено, но код во внутреннемlet-alistне может получить доступ к переменным, связанным внешнимlet-alist.
Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Association-Lists.html