Last active
May 6, 2022 06:54
-
-
Save serioga/a4bae990adbb7b9a4e1bac5d4596566a to your computer and use it in GitHub Desktop.
Create map from sequence using transducer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns map-entries | |
(:import (clojure.lang MapEntry))) | |
(defn map-entries | |
"Returns transducer collecting map-entries from the sequence of keys/values. | |
Map key is `(kf k)` or just key if `kf` is nil. Map value is `(vf k v)` or | |
just value if `vf` is nil. Raises exception in case of odd amount of elements | |
in the input sequence." | |
([] (map-entries nil nil)) | |
([kf] (map-entries kf nil)) | |
([kf vf] | |
(fn [rf] | |
(let [k! (volatile! nil)] | |
(fn | |
([] (rf)) | |
([result] (if-some [k @k!] | |
(throw (ex-info (str "No value supplied for key: " (pr-str k)) {})) | |
(rf result))) | |
([result x] | |
(if-some [k @k!] | |
(do | |
(vreset! k! nil) | |
(rf result (MapEntry. k (cond->> x vf (vf k))))) | |
(do | |
(vreset! k! (cond-> x kf kf)) | |
result)))))))) | |
(defn parse-map | |
"Converts sequence of keys/values to the map with keywordized keys. The `vfs` | |
is a map of optional functions to apply to corresponding key value." | |
[xs vfs] | |
(->> xs (into {} (map-entries keyword (fn [k v] (let [vf (vfs k)] | |
(cond-> v vf vf))))))) | |
(parse-map ["progress" "60" "syncready" "3248" "synctotal" "3248"] | |
{:progress parse-long, :syncready parse-long}) | |
#_=> {:progress 60, :syncready 3248, :synctotal "3248"} | |
;Evaluation count : 1484262 in 6 samples of 247377 calls. | |
; Execution time mean : 489,358779 ns | |
; Execution time std-deviation : 79,326951 ns | |
; Execution time lower quantile : 392,268845 ns ( 2,5%) | |
; Execution time upper quantile : 614,896450 ns (97,5%) | |
; Overhead used : 8,243735 ns | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment