summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur Leonard Andersen <leoc.git@gmail.com>2013-01-22 15:46:33 +0100
committerArthur Leonard Andersen <leoc.git@gmail.com>2013-01-22 15:47:36 +0100
commit0eede1512e5ab1c352c0dbb8610f6f27b9e8ba33 (patch)
tree505d89a11a95f1b2572f964cbe69d9fe6d301aa9
parentf6e0b5a16631a551469a22e140736dabe44b98d7 (diff)
Reimplement kvplist-merge as adviced by spacebat
Spacebat in the #emacs channel suggested to use the loop macro. https://gist.github.com/4595042
-rw-r--r--README.creole5
-rw-r--r--kv-tests.el8
-rw-r--r--kv.el19
3 files changed, 19 insertions, 13 deletions
diff --git a/README.creole b/README.creole
index d5e49ab..1dfd1aa 100644
--- a/README.creole
+++ b/README.creole
@@ -145,9 +145,10 @@ Filter the plist to just those matching //keys//.
[[kvalist->filter-keys]] is actually used to do this work.
-=== kvplist->merge old-plist new-plist ===
+=== kvplist->merge &rest plists ===
-Merge the keys from new-plist into old-plist and return the new plist.
+Merge the 2nd and subsequent plists into the first, clobbering values set
+by lists to the left.
=== kvplist2->filter-keys plist2 &rest keys ===
diff --git a/kv-tests.el b/kv-tests.el
index 7cc6eed..adbaa49 100644
--- a/kv-tests.el
+++ b/kv-tests.el
@@ -186,4 +186,12 @@
(kvplist-merge '(:key1 "value1" :key2 "old value")
'(:key2 "new value" :key3 "entirely new")))))
+(ert-deftest kvplist-merge-multiple ()
+ (should
+ (equal
+ '(:key1 "value1" :key2 "new value" :key3 "overwritten new one" :key4 "second entirely new")
+ (kvplist-merge '(:key1 "value1" :key2 "old value")
+ '(:key2 "new value" :key3 "entirely new")
+ '(:key3 "overwritten new one" :key4 "second entirely new")))))
+
;;; kv-tests.el ends here
diff --git a/kv.el b/kv.el
index 57958e1..2139b28 100644
--- a/kv.el
+++ b/kv.el
@@ -385,17 +385,14 @@ SEXP will describe the structure desired."
(defalias 'map-bind 'kvmap-bind)
-(defun kvplist-merge (old new)
- "Merges two plists. The keys from NEW will overwrite the ones in OLD."
- (let ((key (car new))
- (val (cadr new))
- (new (cddr new)))
- (while (and key val)
- (setq old (plist-put old key val))
- (setq key (car new))
- (setq val (cadr new))
- (setq new (cddr new)))
- old))
+(defun kvplist-merge (&rest plists)
+ "Merge the 2nd and subsequent plists into the first, clobbering values set by lists to the left."
+ (let ((result (car plists))
+ (plists (cdr plists)))
+ (loop for plist in plists do
+ (loop for (key val) on plist by 'cddr do
+ (setq result (plist-put result key val))))
+ result))
(provide 'kv)
(provide 'dotassoc)