diff options
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/emacs-lisp/map.el | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el index 54e802edf4f..74927b6224f 100644 --- a/lisp/emacs-lisp/map.el +++ b/lisp/emacs-lisp/map.el | |||
| @@ -338,7 +338,8 @@ The default implementation delegates to `map-apply'." | |||
| 338 | t)) | 338 | t)) |
| 339 | 339 | ||
| 340 | (defun map-merge (type &rest maps) | 340 | (defun map-merge (type &rest maps) |
| 341 | "Merge into a map of type TYPE all the key/value pairs in MAPS." | 341 | "Merge into a map of type TYPE all the key/value pairs in MAPS. |
| 342 | See `map-into' for all supported values of TYPE." | ||
| 342 | (let ((result (map-into (pop maps) type))) | 343 | (let ((result (map-into (pop maps) type))) |
| 343 | (while maps | 344 | (while maps |
| 344 | ;; FIXME: When `type' is `list', we get an O(N^2) behavior. | 345 | ;; FIXME: When `type' is `list', we get an O(N^2) behavior. |
| @@ -354,7 +355,8 @@ The default implementation delegates to `map-apply'." | |||
| 354 | "Merge into a map of type TYPE all the key/value pairs in MAPS. | 355 | "Merge into a map of type TYPE all the key/value pairs in MAPS. |
| 355 | When two maps contain the same key (`eql'), call FUNCTION on the two | 356 | When two maps contain the same key (`eql'), call FUNCTION on the two |
| 356 | values and use the value returned by it. | 357 | values and use the value returned by it. |
| 357 | MAP can be a list, hash-table or array." | 358 | MAP can be a list, hash-table or array. |
| 359 | See `map-into' for all supported values of TYPE." | ||
| 358 | (let ((result (map-into (pop maps) type)) | 360 | (let ((result (map-into (pop maps) type)) |
| 359 | (not-found (cons nil nil))) | 361 | (not-found (cons nil nil))) |
| 360 | (while maps | 362 | (while maps |
| @@ -458,17 +460,28 @@ If you want to insert an element in place, use `map-put!'." | |||
| 458 | (funcall function index elt)) | 460 | (funcall function index elt)) |
| 459 | array)) | 461 | array)) |
| 460 | 462 | ||
| 461 | (cl-defmethod map-into (map (_type (eql hash-table))) | 463 | (defun map--into-hash (map keyword-args) |
| 462 | "Convert MAP into a hash-table." | 464 | "Convert MAP into a hash-table. |
| 463 | ;; FIXME: Just knowing we want a hash-table is insufficient, since that | 465 | KEYWORD-ARGS are forwarded to `make-hash-table'." |
| 464 | ;; doesn't tell us the test function to use with it! | 466 | (let ((ht (apply #'make-hash-table keyword-args))) |
| 465 | (let ((ht (make-hash-table :size (map-length map) | ||
| 466 | :test 'equal))) | ||
| 467 | (map-apply (lambda (key value) | 467 | (map-apply (lambda (key value) |
| 468 | (setf (map-elt ht key) value)) | 468 | (setf (gethash key ht) value)) |
| 469 | map) | 469 | map) |
| 470 | ht)) | 470 | ht)) |
| 471 | 471 | ||
| 472 | (cl-defmethod map-into (map (_type (eql hash-table))) | ||
| 473 | "Convert MAP into a hash-table." | ||
| 474 | (map--into-hash map (list :size (map-length map) :test 'equal))) | ||
| 475 | |||
| 476 | (cl-defmethod map-into (map (type (head hash-table))) | ||
| 477 | "Convert MAP into a hash-table. | ||
| 478 | TYPE is a list where the car is `hash-table' and the cdr are the keyword-args | ||
| 479 | forwarded to `make-hash-table'. | ||
| 480 | |||
| 481 | Example: | ||
| 482 | (map-into '((1 . 3)) '(hash-table :test eql))" | ||
| 483 | (map--into-hash map (cdr type))) | ||
| 484 | |||
| 472 | (defun map--make-pcase-bindings (args) | 485 | (defun map--make-pcase-bindings (args) |
| 473 | "Return a list of pcase bindings from ARGS to the elements of a map." | 486 | "Return a list of pcase bindings from ARGS to the elements of a map." |
| 474 | (seq-map (lambda (elt) | 487 | (seq-map (lambda (elt) |