I have a hash-map. I want to iterate over the values and replace each of them depending on the value's type. If the value is an integer, replace it with true, and if not, replace it with false. I want this to return a new hash-map with every value updated to either true or false.
(defn my-function [hash-map]
(loop [hash-map hash-map]
(for [value (vals hash-map)]
(if (= Integer (type value))
(recur (assoc hash-map key true))
(recur (assoc hash-map key false))))))
That won't work because Clojure Can only recur from tail position, but that's the general idea of what I want to do. Any ideas of an effective way to do this? if-let and update-in seemed like potential solutions, but I can't quite grasp them.
(reduce-kv (fn [m k v] (assoc m k (= Integer (type v)))) {} m)
Or even shorter if you prefer:
(reduce-kv #(assoc %1 %2 (= Integer (type %3))) {} m)
And to keep the type of map (hash vs. sorted):
(reduce-kv #(assoc %1 %2 (= Integer (type %3))) (empty m) m)
Caveat: the last one doesn't work with records.
The operation you've outlined -- transforming each value in a map, independently -- is actually already implemented in the Functor module.
What you need to do to use it is implement your function that transforms a single value, then fmap it over your map:
(fmap your-function your-map)
(Don't be misled by the name fmap -- this operation is not specific to maps. Since it's a generic function, it works on anything that has a Functor instance, which also includes lists, sets, and vectors). This is a structure-preserving operation: none of the keys will be changed, no new ones will be added, none will be removed.
If you'd prefer to avoid using a generic function, just check out the implementation:
(defmethod fmap clojure.lang.IPersistentMap
[f m]
(into (empty m) (for [[k v] m] [k (f v)]))) ;;; <== the important part!!
where f = your-function and m = your-map.
This library has been moved (is moving? will be moved?) to clojure.algo.generic.functor. See this for more information, and this for the source.
(letfn [(map-vals [m f]
(into {} (for [[k v] m]
[k (f v)])))]
(map-vals m #(= Integer (type %))))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With