Я не нашел стандартной библиотечной функции Elisp для объединения двух списков свойств, например:
(setq pl nil)
(setq pl (plist-put pl 'key-1 'value-1))
(setq pl (plist-put pl 'key-2 'value-2))
Я мог бы что-то построить с помощью dolist
, но прежде чем я это сделаю, я хотел бы убедиться, что я не пропускаю существующую функцию в какой-то библиотеке.
Обновления, основанные на комментариях :
- В ответ на «многогранный» комментарий:
Я полагаю, что такой функции нет, потому что есть разные (и, возможно, правильные) ответы на вопрос: что делать, если у вас есть дубликаты имен свойств с разными значениями?
Да, есть вопрос о том, как объединить дубликаты, но есть относительно немного способов решить эту проблему. Я вижу два общих подхода. Во-первых, порядок аргументов может разрешать дубликаты; например, самые правые победы, как при слиянии Clojure . Во-вторых, слияние может делегироваться пользовательской функции обратного вызова, как в слиянии Ruby .
В любом случае, тот факт, что существуют разные способы сделать это, не мешает многим другим языковым стандартным библиотекам предоставлять функцию слияния. Тот же самый общий аргумент можно сказать о сортировке, но Elisp предоставляет функции сортировки.
- "Не могли бы вы уточнить?" / «Пожалуйста, уточните, какое поведение вы ищете.»
Вообще говоря, я открыт для того, что использует сообщество Elisp. Если вы хотите конкретный пример, вот один пример, который будет работать:
(a-merge-function '(k1 1) '(k2 2 k3 3) '(k3 0))
И возвращает
'(k1 1 k2 2 k3 0))
Это был бы самый правый стиль, как слияние Clojure.
- "Это списки, так что просто добавить?"
Нет, append
не сохраняет семантику списка свойств . Эта:
(append '(k1 1 k2 2) '(k2 0))
Возвращает это:
(k1 1 k2 2 k2 0)
append - это встроенная функция в `C исходном коде '.
(добавить и отдохнуть ПОСЛЕДОВАТЕЛЬНОСТИ)
Объединить все аргументы и сделать результат списком. Результатом является список, элементы которого являются элементами всех аргументов. Каждый аргумент может быть списком, вектором или строкой. Последний аргумент не копируется, просто используется как хвост нового списка.
- «И ваш пример не показывает ничего похожего на слияние - он даже не показывает два списка свойств».
Да, это так; это делает слияние шаг за шагом. Это показывает, как выполнение слияния с использованием документированных функций списка свойств Elisp мучительно многословно:
(setq pl nil)
(setq pl (plist-put pl 'key-1 'value-1))
(setq pl (plist-put pl 'key-2 'value-2))
Просто отобразите полученное выходное значение из pl
:
(key-1 value-1 key-2 value-2)
Повторюсь, я могу написать функцию для решения этой проблемы, но сначала я хотел выяснить, существует ли такая функция где-то в общем пользовании.
Наконец, если бы вы отклонили вопрос, потому что вы нашли его неясным, я бы попросил вас пересмотреть его сейчас, когда я приложил некоторые усилия, чтобы уточнить. Это не недостаток исследований. Документация Elisp по «Спискам» не отвечает на этот вопрос.
источник
append
?append
:(let ((args '((:a 1 :b 1) (:b 2) (:a 3)))) (apply #'append (reverse args))) => (:a 3 :b 2 :a 1 :b 1)
это то же самое, что(:a 3 :b 2 :a 1)
и при использовании только функций plist для доступа к plist.plist-get
ни другое,plist-member
похоже, не волнует, есть ли несколько идентичных ключей. Похоже, они ведут себя аналогично спискам в этом отношении(plist-get '(:a "a" :b "b" :a "c") :a) ==> "a"
. Между тем(plist-put '(:a "a" :b "b" :a "c") :a "d")
заменяет значение первого:a
ключа, а не второго.Ответы:
Org-mode, включенный в Emacs, имеет функцию слияния plist:
Чтобы использовать его, вам нужно
(require 'org)
сначала загрузить файл. К сожалению, это очень большой файл, 900 + КБ, поэтому он не очень полезен в качестве служебной библиотеки. Было бы неплохо иметь что-то похожее на стандартную упаковку.Недавно я запустил очень маленький и понял, что списки и списки не обрабатываются одинаково по аргументам - например, (plist-get LIST KEY) против (assoc KEY LIST), что должно быть неким печальным пережитком оптимизации (или?) ,
Но да, Emacs действительно нуждается в хорошей библиотеке plist - я не сталкивался с одной в моих поисках, но все еще возможно, что где-то есть такая, иначе нам придется ее запустить и поместить в Elpa / Melpa. ,
Было бы неплохо иметь библиотеку alist с тем же интерфейсом.
источник
Чтение руководства и просмотр списка из
C-u C-h a plist RET
не приводит ни к одной функции для объединения двух списков свойств. Расширения Common Lisp не предоставляют какой-либо функции специально для работы со списками свойств, только поддержка размещения (getf
/setf
/…). Так что вам нужно либо положиться на стороннюю библиотеку, либо свернуть свою.Прокатить свой не так уж сложно. Эта реализация использует последнее значение в случае конфликта.
источник
copy-sequence
первый, а не остальные? А также, вы можете очистить гнездового немного сcadr
иcddr
.org-combine-plists
(ниже) более или менее очищенная версия. Я до сих пор не понимаю, зачем имcopy-sequence
машина.Я знаю, что на этот вопрос уже дан ответ, но если кому-то это интересно, я взял
org
реализацию и немного поиграл в нее.источник