Je n'ai pas trouvé de fonction de bibliothèque Elisp standard pour fusionner deux listes de propriétés, comme ceci:
(setq pl nil)
(setq pl (plist-put pl 'key-1 'value-1))
(setq pl (plist-put pl 'key-2 'value-2))
Je pourrais construire quelque chose avec dolist
, mais avant de le faire, je voudrais vérifier que je ne néglige pas une fonction existante dans une bibliothèque.
Mises à jour, basées sur les commentaires :
- En réponse au commentaire "multiple":
J'imagine qu'il n'y a pas une telle fonction car il existe des réponses différentes (et éventuellement valides) à la question: que faire lorsque vous avez des noms de propriété en double avec des valeurs distinctes?
Oui, il y a une question sur la façon de fusionner les doublons, mais il existe relativement peu de façons de résoudre ce problème. Je vois deux approches générales. Premièrement, l'ordre des arguments pourrait résoudre les doublons; par exemple, le plus à droite gagne, comme dans la fusion de Clojure . Deuxièmement, la fusion pourrait déléguer à une fonction de rappel fournie par l'utilisateur, comme dans la fusion de Ruby .
Dans tous les cas, le fait qu'il existe différentes façons de le faire n'empêche pas de nombreuses autres bibliothèques standard de langage de fournir une fonction de fusion. Le même argument général pourrait être dit du tri, et pourtant Elisp fournit une fonctionnalité de tri.
- "Pourriez-vous élaborer?" / "Veuillez spécifier précisément le comportement que vous recherchez."
D'une manière générale, je suis ouvert à ce que la communauté Elisp utilise. Si vous souhaitez un exemple spécifique, voici un exemple qui fonctionnerait:
(a-merge-function '(k1 1) '(k2 2 k3 3) '(k3 0))
Et retourne
'(k1 1 k2 2 k3 0))
Ce serait un style gagnant à droite, comme la fusion de Clojure.
- "Ce sont des listes, alors ajoutez-les?"
Non, append
ne conserve pas la sémantique des listes de propriétés . Cette:
(append '(k1 1 k2 2) '(k2 0))
Renvoie ceci:
(k1 1 k2 2 k2 0)
append est une fonction intégrée au `code source C '.
(ajouter et reposer des séquences)
Concatène tous les arguments et fait du résultat une liste. Le résultat est une liste dont les éléments sont les éléments de tous les arguments. Chaque argument peut être une liste, un vecteur ou une chaîne. Le dernier argument n'est pas copié, il est juste utilisé comme queue de la nouvelle liste.
- "Et votre exemple ne montre rien de tel qu'une fusion - il n'affiche même pas deux listes de propriétés."
Oui; il fait la fusion étape par étape. Il montre comment effectuer une fusion à l'aide des fonctions de liste de propriétés documentées d'Elisp est douloureusement détaillé:
(setq pl nil)
(setq pl (plist-put pl 'key-1 'value-1))
(setq pl (plist-put pl 'key-2 'value-2))
Affichez simplement la valeur de sortie résultante de pl
:
(key-1 value-1 key-2 value-2)
Pour réitérer, je suis capable d'écrire une fonction pour résoudre ce problème, mais je voulais d'abord savoir si une telle fonction existe quelque part dans l'usage courant.
Enfin, si vous avez voté contre la question parce que vous l'avez trouvée peu claire, je vous demanderais de reconsidérer maintenant que j'ai fait des efforts pour clarifier. Ce n'est pas un manque de recherche. La documentation Elisp sur les "Listes" ne répond pas à la question.
append
: (let ((args '((:a 1 :b 1) (:b 2) (:a 3)))) (apply #'append (reverse args))) => (:a 3 :b 2 :a 1 :b 1)
ce qui est le même tant (:a 3 :b 2 :a 1)
que vous n'utilisez que les fonctions plist pour accéder au plist.
plist-get
ne plist-member
semble se soucier s'il y a plusieurs clés identiques. On dirait qu'ils se comportent de façon analogue à alistes à cet égard: (plist-get '(:a "a" :b "b" :a "c") :a) ==> "a"
. Pendant ce temps, (plist-put '(:a "a" :b "b" :a "c") :a "d")
remplace la valeur de la première :a
clé mais pas la seconde.
append
?