Я не нашел стандартной библиотечной функции 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
: (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
ключа, а не второго.
append
?