diff options
author | Andrea Corallo <akrl@sdf.org> | 2019-10-11 12:18:21 -0400 |
---|---|---|
committer | Stefan Monnier <monnier@iro.umontreal.ca> | 2019-10-11 12:18:21 -0400 |
commit | 421db07d061cdc493300b30646c2acd13f26d8f3 (patch) | |
tree | ce05322b0458a08547371254aaad0623235fbe77 /lisp/emacs-lisp/map.el | |
parent | 65cda95be4f69c32b16364c95cb7c08971bc9397 (diff) | |
download | emacs-421db07d061cdc493300b30646c2acd13f26d8f3.tar.gz emacs-421db07d061cdc493300b30646c2acd13f26d8f3.tar.bz2 emacs-421db07d061cdc493300b30646c2acd13f26d8f3.zip |
* lisp/emacs-lisp/map.el (map-into) <hash-table>: Allow keyword args
(map--into-hash): New function, extracted from `map-into <hash-table>`.
Speed it up a bit by using gethash instead of map-elt when we know
we're accessing a hash table.
* test/lisp/emacs-lisp/map-tests.el (test-map-into): Add corresponding test.
Diffstat (limited to 'lisp/emacs-lisp/map.el')
-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'." t)) (defun map-merge (type &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. +See `map-into' for all supported values of TYPE." (let ((result (map-into (pop maps) type))) (while maps ;; FIXME: When `type' is `list', we get an O(N^2) behavior. @@ -354,7 +355,8 @@ The default implementation delegates to `map-apply'." "Merge into a map of type TYPE all the key/value pairs in MAPS. When two maps contain the same key (`eql'), call FUNCTION on the two 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. +See `map-into' for all supported values of TYPE." (let ((result (map-into (pop maps) type)) (not-found (cons nil nil))) (while maps @@ -458,17 +460,28 @@ If you want to insert an element in place, use `map-put!'." (funcall function index elt)) array)) -(cl-defmethod map-into (map (_type (eql hash-table))) - "Convert MAP into a hash-table." - ;; FIXME: Just knowing we want a hash-table is insufficient, since that - ;; doesn't tell us the test function to use with it! - (let ((ht (make-hash-table :size (map-length map) - :test 'equal))) +(defun map--into-hash (map keyword-args) + "Convert MAP into a hash-table. +KEYWORD-ARGS are forwarded to `make-hash-table'." + (let ((ht (apply #'make-hash-table keyword-args))) (map-apply (lambda (key value) - (setf (map-elt ht key) value)) + (setf (gethash key ht) value)) map) ht)) +(cl-defmethod map-into (map (_type (eql hash-table))) + "Convert MAP into a hash-table." + (map--into-hash map (list :size (map-length map) :test 'equal))) + +(cl-defmethod map-into (map (type (head hash-table))) + "Convert MAP into a hash-table. +TYPE is a list where the car is `hash-table' and the cdr are the keyword-args +forwarded to `make-hash-table'. + +Example: + (map-into '((1 . 3)) '(hash-table :test eql))" + (map--into-hash map (cdr type))) + (defun map--make-pcase-bindings (args) "Return a list of pcase bindings from ARGS to the elements of a map." (seq-map (lambda (elt) |