aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtur Malabarba2015-11-07 12:45:18 +0000
committerArtur Malabarba2015-11-10 13:04:30 +0000
commitcbaa04014e0c9efdfc6393bccde0e6579b5d7051 (patch)
treea0fc99cbe4225fc9ff5b5ed04fd5f07441e9cbc8
parentcbc51211f9e4f8f3d4b8a1feaa6cbfd2fd4ac1ca (diff)
downloademacs-cbaa04014e0c9efdfc6393bccde0e6579b5d7051.tar.gz
emacs-cbaa04014e0c9efdfc6393bccde0e6579b5d7051.zip
* lisp/emacs-lisp/map.el (map-merge-with): New function
* test/automated/map-tests.el (test-map-merge-with): New test
-rw-r--r--lisp/emacs-lisp/map.el25
-rw-r--r--test/automated/map-tests.el7
2 files changed, 27 insertions, 5 deletions
diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el
index 5ef51f12d96..7ff9031b08d 100644
--- a/lisp/emacs-lisp/map.el
+++ b/lisp/emacs-lisp/map.el
@@ -279,9 +279,9 @@ MAP can be a list, hash-table or array."
279MAP can be a list, hash-table or array." 279MAP can be a list, hash-table or array."
280 (catch 'map--break 280 (catch 'map--break
281 (map-apply (lambda (key value) 281 (map-apply (lambda (key value)
282 (or (funcall pred key value) 282 (or (funcall pred key value)
283 (throw 'map--break nil))) 283 (throw 'map--break nil)))
284 map) 284 map)
285 t)) 285 t))
286 286
287(defun map-merge (type &rest maps) 287(defun map-merge (type &rest maps)
@@ -291,8 +291,23 @@ MAP can be a list, hash-table or array."
291 (let (result) 291 (let (result)
292 (while maps 292 (while maps
293 (map-apply (lambda (key value) 293 (map-apply (lambda (key value)
294 (setf (map-elt result key) value)) 294 (setf (map-elt result key) value))
295 (pop maps))) 295 (pop maps)))
296 (map-into result type)))
297
298(defun map-merge-with (type function &rest maps)
299 "Merge into a map of type TYPE all the key/value pairs in MAPS.
300When two maps contain the same key, call FUNCTION on the two
301values and use the value returned by it.
302MAP can be a list, hash-table or array."
303 (let (result)
304 (while maps
305 (map-apply (lambda (key value)
306 (setf (map-elt result key)
307 (if (map-contains-key result key)
308 (funcall function (map-elt result key) value)
309 value)))
310 (pop maps)))
296 (map-into result type))) 311 (map-into result type)))
297 312
298(defun map-into (map type) 313(defun map-into (map type)
diff --git a/test/automated/map-tests.el b/test/automated/map-tests.el
index 8693415a784..1a759b523a5 100644
--- a/test/automated/map-tests.el
+++ b/test/automated/map-tests.el
@@ -320,5 +320,12 @@ Evaluate BODY for each created map.
320 (should (= b 2)) 320 (should (= b 2))
321 (should (null c)))) 321 (should (null c))))
322 322
323(ert-deftest test-map-merge-with ()
324 (should (equal (map-merge-with 'list #'+
325 '((1 . 2))
326 '((1 . 3) (2 . 4))
327 '((1 . 1) (2 . 5) (3 . 0)))
328 '((3 . 0) (2 . 9) (1 . 6)))))
329
323(provide 'map-tests) 330(provide 'map-tests)
324;;; map-tests.el ends here 331;;; map-tests.el ends here