diff options
author | Arthur Leonard Andersen <leoc.git@gmail.com> | 2013-01-22 15:46:33 +0100 |
---|---|---|
committer | Arthur Leonard Andersen <leoc.git@gmail.com> | 2013-01-22 15:47:36 +0100 |
commit | 0eede1512e5ab1c352c0dbb8610f6f27b9e8ba33 (patch) | |
tree | 505d89a11a95f1b2572f964cbe69d9fe6d301aa9 | |
parent | f6e0b5a16631a551469a22e140736dabe44b98d7 (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.creole | 5 | ||||
-rw-r--r-- | kv-tests.el | 8 | ||||
-rw-r--r-- | kv.el | 19 |
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 @@ -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) |