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.
fuente
append
?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
niplist-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.Respuestas:
Org-mode, que se incluye con Emacs, tiene una función de fusión de plist:
Para usarlo,
(require 'org)
primero debe cargar el archivo. Desafortunadamente, es un archivo muy grande, 900 + KB, por lo que no es realmente útil como biblioteca de utilidades. Sería bueno tener algo así como un paquete plist estándar.Hace poco comencé uno muy pequeño y me di cuenta de que las listas y listas no son tratadas de la misma manera, en términos de argumentos, por ejemplo (plist-get LIST KEY) vs (assoc KEY LIST), que debe ser una desafortunada reliquia de optimización (o?) .
Pero sí, Emacs necesita una buena biblioteca plist: no encontré una en mi búsqueda, pero aún es posible que haya una en algún lugar, o tendremos que comenzar una y ponerla en Elpa / Melpa .
También sería bueno tener una biblioteca de listas con la misma interfaz.
fuente
Leer el manual y explorar la lista
C-u C-h a plist RET
no activa ninguna función para fusionar dos listas de propiedades. Las extensiones Common Lisp no proporcionan ninguna función específica para actuar en listas de propiedades, solo colocan (getf
/setf
/ ...) soporte. Por lo tanto, debe confiar en una biblioteca de terceros o crear una propia.Rodar el tuyo no es demasiado difícil. Esta implementación utiliza el último valor en caso de conflicto.
fuente
copy-sequence
la primera lista pero no las otras? Y también, puedes limpiar un poco la anidación concadr
ycddr
.org-combine-plists
(abajo) es más o menos la versión limpiada. Todavía no entiendo por quécopy-sequence
el auto.Sé que esto ya ha sido respondido, pero en caso de que alguien esté interesado, tomé la
org
implementación y jugué un poco de código de golf.fuente