hi, first of all, I'm really enjoying specter and how easy makes many things, but I have a case where I'm thinking that maybe is better to not use specter. I have a map where I want to remove and rename some keys. e.g. with specter:
(->> {:id 1 :data_val 5 :bad nil}
(s/select-one (s/submap [:id :data_val]))
(s/transform [s/MAP-KEYS] #(case % :data_val :value %))
and without
(-> {:id 1 :data_val 5 :bad nil}
(select-keys [:id :data_val])
(clojure.set/rename-keys {:data_val :value}))
what do you think? makes sense to use specter here? Is there a better way to do it with specter?Almost the same perf I think that w/o spec is more readable, in this case.
(time
(doseq [i (range 1000000)]
(->> {:id 1 :data_val 5 :bad nil}
(s/select-one (s/submap [:id :data_val]))
(s/transform [s/MAP-KEYS] #(case % :data_val :value %)))))
"Elapsed time: 1031.939844 msecs"
=> nil
(time
(doseq [i (range 1000000)]
(-> {:id 1 :data_val 5 :bad nil}
(select-keys [:id :data_val])
(clojure.set/rename-keys {:data_val :value}))))
"Elapsed time: 1794.127254 msecs"
Mine is a bit faster. And has data/explicit params.
(let [n 10000000]
(prn "specter")
(time
(doseq [i (range n)]
(->> {:id 1 :data_val 5 :bad nil}
(s/select-one (s/submap [:id :data_val]))
(s/transform [s/MAP-KEYS] #(case % :data_val :value %)))))
(prn "@souenzzo")
(time
(doseq [i (range n)]
(let [from->to {:data_val :value
:id :id}]
(reduce-kv (fn [acc k v]
(if (contains? from->to k)
(assoc acc (from->to k) v)
acc)) {} {:id 1 :data_val 5 :bad nil})))))
@souenzzo thanks for your example, didn't know about reduce-kv