No he encontrado una función de biblioteca estándar de Elisp para fusionar dos listas de propiedades, como esta:
(setq pl nil)
(setq pl (plist-put pl 'key-1 'value-1))
(setq pl (plist-put pl 'key-2 'value-2))
Podría construir algo con dolist
, pero antes de hacerlo, me gustaría comprobar que no estoy pasando por alto una función existente en alguna biblioteca.
Actualizaciones, basadas en los comentarios :
- En respuesta al comentario de "muchas formas":
Me imagino que no existe tal función porque hay respuestas diferentes (y posiblemente válidas) posibles a la pregunta: ¿qué hacer cuando tiene nombres de propiedad duplicados con valores distintos?
Sí, hay una pregunta sobre cómo combinar duplicados, pero hay relativamente pocas formas de abordarlo. Veo dos enfoques generales. Primero, el orden del argumento podría resolver los duplicados; Por ejemplo, la derecha gana, como en la fusión de Clojure . En segundo lugar, la fusión podría delegarse en una función de devolución de llamada proporcionada por el usuario, como en la fusión de Ruby .
En cualquier caso, el hecho de que haya diferentes formas de hacerlo no impide que muchas bibliotecas estándar de otros idiomas proporcionen una función de fusión. Se podría decir el mismo argumento general sobre la clasificación, y sin embargo, Elisp proporciona la funcionalidad de clasificación.
- "¿Podrías dar más detalles?" / "Especifique con precisión el comportamiento que está buscando".
En términos generales, estoy abierto a lo que usa la comunidad de Elisp. Si desea un ejemplo específico, este sería un ejemplo que funcionaría:
(a-merge-function '(k1 1) '(k2 2 k3 3) '(k3 0))
Y vuelve
'(k1 1 k2 2 k3 0))
Este sería un estilo de extrema derecha, como la fusión de Clojure.
- "Son listas, así que ¿solo agregar?"
No, append
no conserva la semántica de la lista de propiedades . Esta:
(append '(k1 1 k2 2) '(k2 0))
Devuelve esto:
(k1 1 k2 2 k2 0)
append es una función incorporada en el 'código fuente C'.
(agregar y descansar SECUENCIAS)
Concatena todos los argumentos y convierte el resultado en una lista. El resultado es una lista cuyos elementos son los elementos de todos los argumentos. Cada argumento puede ser una lista, un vector o una cadena. El último argumento no se copia, solo se usa como la cola de la nueva lista.
- "Y su ejemplo no muestra nada parecido a una fusión, ni siquiera muestra dos listas de propiedades".
Sí lo hace; se fusiona paso a paso. Muestra cómo hacer una fusión usando las funciones de la lista de propiedades documentadas de Elisp es dolorosamente detallado:
(setq pl nil)
(setq pl (plist-put pl 'key-1 'value-1))
(setq pl (plist-put pl 'key-2 'value-2))
Simplemente muestre el valor de salida resultante de pl
:
(key-1 value-1 key-2 value-2)
Para reiterar, soy capaz de escribir una función para resolver este problema, pero primero quería averiguar si dicha función existe en algún lugar de uso común.
Finalmente, si rechazó la pregunta porque no le quedó claro, le pediría que reconsiderara ahora que me he esforzado por aclarar. Esto no es una falta de investigación. La documentación de Elisp sobre "Listas" no responde la pregunta.
append
: (let ((args '((:a 1 :b 1) (:b 2) (:a 3)))) (apply #'append (reverse args))) => (:a 3 :b 2 :a 1 :b 1)
que es lo mismo (:a 3 :b 2 :a 1)
, siempre y cuando solo use las funciones plist para acceder a la lista.
plist-get
ni plist-member
parece importarle si hay varias claves idénticas. Parece que se comportan de forma análoga a alistas a este respecto: (plist-get '(:a "a" :b "b" :a "c") :a) ==> "a"
. Mientras tanto, (plist-put '(:a "a" :b "b" :a "c") :a "d")
reemplaza el valor de la primera :a
clave pero no la segunda.
append
?