mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-23 22:20:24 -08:00
map.el (map-merge*): Use `map-into' at beginning rather than end
* lisp/emacs-lisp/map.el (map-merge): Use `map-into' for the first map, and don't use of an intermediate alist. (map-merge-with): Same, plus use `cl-callf' to try and avoid performing 3 lookups per inner iteration.
This commit is contained in:
parent
574cd99692
commit
44eca25a4b
1 changed files with 18 additions and 11 deletions
|
|
@ -43,6 +43,7 @@
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(require 'seq)
|
(require 'seq)
|
||||||
|
(eval-when-compile (require 'cl-lib))
|
||||||
|
|
||||||
(pcase-defmacro map (&rest args)
|
(pcase-defmacro map (&rest args)
|
||||||
"Build a `pcase' pattern matching map elements.
|
"Build a `pcase' pattern matching map elements.
|
||||||
|
|
@ -282,27 +283,33 @@ MAP can be a list, hash-table or array."
|
||||||
"Merge into a map of type TYPE all the key/value pairs in MAPS.
|
"Merge into a map of type TYPE all the key/value pairs in MAPS.
|
||||||
|
|
||||||
MAP can be a list, hash-table or array."
|
MAP can be a list, hash-table or array."
|
||||||
(let (result)
|
(let ((result (map-into (pop maps) type)))
|
||||||
(while maps
|
(while maps
|
||||||
|
;; FIXME: When `type' is `list', we get an O(N^2) behavior.
|
||||||
|
;; For small tables, this is fine, but for large tables, we
|
||||||
|
;; should probably use a hash-table internally which we convert
|
||||||
|
;; to an alist in the end.
|
||||||
(map-apply (lambda (key value)
|
(map-apply (lambda (key value)
|
||||||
(setf (map-elt result key) value))
|
(setf (map-elt result key) value))
|
||||||
(pop maps)))
|
(pop maps)))
|
||||||
(map-into result type)))
|
result))
|
||||||
|
|
||||||
(defun map-merge-with (type function &rest maps)
|
(defun map-merge-with (type function &rest maps)
|
||||||
"Merge into a map of type TYPE all the key/value pairs in MAPS.
|
"Merge into a map of type TYPE all the key/value pairs in MAPS.
|
||||||
When two maps contain the same key, call FUNCTION on the two
|
When two maps contain the same key, call FUNCTION on the two
|
||||||
values and use the value returned by it.
|
values and use the value returned by it.
|
||||||
MAP can be a list, hash-table or array."
|
MAP can be a list, hash-table or array."
|
||||||
(let (result)
|
(let ((result (map-into (pop maps) type))
|
||||||
|
(not-found (cons nil nil)))
|
||||||
(while maps
|
(while maps
|
||||||
(map-apply (lambda (key value)
|
(map-apply (lambda (key value)
|
||||||
(setf (map-elt result key)
|
(cl-callf (lambda (old)
|
||||||
(if (map-contains-key result key)
|
(if (eq old not-found)
|
||||||
(funcall function (map-elt result key) value)
|
value
|
||||||
value)))
|
(funcall function old value)))
|
||||||
|
(map-elt result key not-found)))
|
||||||
(pop maps)))
|
(pop maps)))
|
||||||
(map-into result type)))
|
result))
|
||||||
|
|
||||||
(defun map-into (map type)
|
(defun map-into (map type)
|
||||||
"Convert the map MAP into a map of type TYPE.
|
"Convert the map MAP into a map of type TYPE.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue