diff options
| author | Artur Malabarba | 2015-11-07 12:45:18 +0000 |
|---|---|---|
| committer | Artur Malabarba | 2015-11-10 13:04:30 +0000 |
| commit | cbaa04014e0c9efdfc6393bccde0e6579b5d7051 (patch) | |
| tree | a0fc99cbe4225fc9ff5b5ed04fd5f07441e9cbc8 | |
| parent | cbc51211f9e4f8f3d4b8a1feaa6cbfd2fd4ac1ca (diff) | |
| download | emacs-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.el | 25 | ||||
| -rw-r--r-- | test/automated/map-tests.el | 7 |
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." | |||
| 279 | MAP can be a list, hash-table or array." | 279 | MAP 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. | ||
| 300 | When two maps contain the same key, call FUNCTION on the two | ||
| 301 | values and use the value returned by it. | ||
| 302 | MAP 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 |