Spec-Zone.ru › Elisp

Использование списков как множеств

Список может представлять неупорядоченное математическое множество — просто рассмотрите значение как элемент множества, если оно встречается в списке, и игнорируйте порядок списка. Для формирования объединения двух множеств используйте append (если вас не смущает наличие дублирующих элементов). Вы можете удалить equal дубликаты, используя delete-dups или seq-uniq. Другие полезные функции для множеств включают memq и delq, а также их equal версии, member и delete.

Примечание для Common Lisp: Common Lisp имеет функции union (которая избегает дублирующих элементов) и intersection для операций над множествами. В Emacs Lisp аналогичные возможности предоставляются библиотекой cl-lib. См. Списки как множества в Расширения Common Lisp.

Функция: memq объект список

Эта функция проверяет, является ли объект элементом списка. Если это так, memq возвращает список, начинающийся с первого вхождения объекта. В противном случае, она возвращает nil. Буква «q» в memq говорит о том, что она использует eq для сравнения объекта с элементами списка. Например:

(memq 'b '(a b c b a))
     ⇒ (b c b a)
(memq '(2) '((1) (2)))    ; The two (2)s need not be eq.
     ⇒ Unspecified; might be nil or ((2)).
Функция: delq объект список

Эта функция деструктивно удаляет все элементы eq до объекта из списка и возвращает полученный список. Буква «q» в delq говорит о том, что она использует eq для сравнения объекта с элементами списка, как в memq и remq.

Как правило, при вызове delq, вы должны использовать возвращаемое значение, присваивая его переменной, которая содержала исходный список. Причина этого объясняется ниже.

Функция delq удаляет элементы из начала списка, просто перемещаясь по списку и возвращая подсписок, начинающийся после этих элементов. Например:

(delq 'a '(a b c)) ≡ (cdr '(a b c))

Когда удаляемый элемент встречается посередине списка, удаление его включает изменение CDR (см. Setcdr).

(setq sample-list (list 'a 'b 'c '(4)))
     ⇒ (a b c (4))
(delq 'a sample-list)
     ⇒ (b c (4))
sample-list
     ⇒ (a b c (4))
(delq 'c sample-list)
     ⇒ (a b (4))
sample-list
     ⇒ (a b (4))

Обратите внимание, что (delq 'c sample-list) изменяет sample-list для вырезания третьего элемента, но (delq 'a sample-list) ничего не вырезает — она просто возвращает более короткий список. Не предполагайте, что переменная, которая ранее содержала аргумент список, теперь содержит меньше элементов или что она все еще содержит исходный список! Сохраните результат delq и используйте его. Чаще всего мы сохраняем результат обратно в переменную, которая содержала исходный список:

(setq flowers (delq 'rose flowers))

В следующем примере, (list 4) , которое delq пытается сопоставить, и (4) в sample-list являются equal, но не eq:

(delq (list 4) sample-list)
     ⇒ (a c (4))

Если вы хотите удалить элементы, которые equal заданному значению, используйте delete (см. ниже).

Функция: remq объект список

Эта функция возвращает копию списка, из которого удалены все элементы, eq до объекта. Буква «q» в remq говорит о том, что она использует eq для сравнения объекта с элементами list.

(setq sample-list (list 'a 'b 'c 'a 'b 'c))
     ⇒ (a b c a b c)
(remq 'a sample-list)
     ⇒ (b c b c)
sample-list
     ⇒ (a b c a b c)
Функция: memql объект список

Функция memql проверяет, является ли объект элементом списка, сравнивая члены с объектом с помощью eql, поэтому элементы с плавающей запятой сравниваются по значению. Если объект является членом, memql возвращает список, начинающийся с его первого вхождения в список. В противном случае, она возвращает nil.

Сравните это с memq:

(memql 1.2 '(1.1 1.2 1.3))  ; 1.2 and 1.2 are eql.
     ⇒ (1.2 1.3)
(memq 1.2 '(1.1 1.2 1.3))  ; The two 1.2s need not be eq.
     ⇒ Unspecified; might be nil or (1.2 1.3).

Следующие три функции похожи на memq, delq и remq, но используют equal вместо eq для сравнения элементов. См. Предикаты равенства.

Функция: member объект список

Функция member проверяет, является ли объект элементом списка, сравнивая члены с объектом с помощью equal. Если объект является членом, member возвращает список, начинающийся с его первого вхождения в список. В противном случае, она возвращает nil.

Сравните это с memq:

(member '(2) '((1) (2)))  ; (2) and (2) are equal.
     ⇒ ((2))
(memq '(2) '((1) (2)))    ; The two (2)s need not be eq.
     ⇒ Unspecified; might be nil or (2).
;; Two strings with the same contents are equal.
(member "foo" '("foo" "bar"))
     ⇒ ("foo" "bar")
Функция: delete объект последовательность

Эта функция удаляет все элементы equal до объекта из последовательности и возвращает полученную последовательность.

Если последовательность является списком, delete к delq так же, как member к memq: она использует equal для сравнения элементов с объектом, как в member; когда она находит совпадающий элемент, она вырезает его точно так же, как и delq. Как и в случае с delq, вы обычно должны использовать возвращаемое значение, присваивая его переменной, которая содержала исходный список.

Если последовательность является вектором или строкой, delete возвращает копию sequence с удаленными всеми элементами, equal до object.

Например:

(setq l (list '(2) '(1) '(2)))
(delete '(2) l)
     ⇒ ((1))
l
     ⇒ ((2) (1))
;; If you want to change l reliably,
;; write (setq l (delete '(2) l)).
(setq l (list '(2) '(1) '(2)))
(delete '(1) l)
     ⇒ ((2) (2))
l
     ⇒ ((2) (2))
;; In this case, it makes no difference whether you set l,
;; but you should do so for the sake of the other case.
(delete '(2) [(2) (1) (2)])
     ⇒ [(1)]
Функция: remove объект последовательность

Эта функция является неразрушающим аналогом delete. Она возвращает копию sequence, списка, вектора или строки, с удаленными элементами, equal до object. Например:

(remove '(2) '((2) (1) (2)))
     ⇒ ((1))
(remove '(2) [(2) (1) (2)])
     ⇒ [(1)]

Примечание для Common Lisp: Функции member, delete и remove в GNU Emacs Lisp взяты из Maclisp, а не из Common Lisp. Версии Common Lisp не используют equal для сравнения элементов.

Функция: member-ignore-case объект список

Эта функция похожа на member, за исключением того, что объект должен быть строкой, и она игнорирует различия в регистре букв и представлении текста: прописные и строчные буквы считаются равными, а однобайтовые строки преобразуются в многобайтовые перед сравнением.

Функция: delete-dups список

Эта функция деструктивно удаляет все equal дубликаты из списка, сохраняет результат в списке и возвращает его. Из нескольких equal вхождений элемента в списке, delete-dups сохраняет первое. См. seq-uniq для неразрушающей операции (см. Функции последовательностей).

См. также функцию add-to-list, в Переменные списков, для способа добавления элемента в список, хранящийся в переменной и используемый как множество.

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/Sets-And-Lists.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API