简体   繁体   中英

Clojure: how to apply a function to hash-map values, some of which are vectors

I'm trying to change the type of the values in my hash map (the hash-map contains data imported from a csv file, which imports everything as a string, creating this problem) from string to float:

Example Input:

(def toydata {"EGFR" ["12.34" "4.45" "1.32"], "MYCN" "5.11", "ABC9" ["3.21" "1.32"]})

What I want:

{"EGFR" [12.4 4.45 1.32] "MYCN" 5.11 "ABC9" [3.21 1.32]}

I found a great example here on SO by Thomas shown below, however it doesn't seem to work for map values that are vectors:

(defn remap [m f] 
  (reduce (fn [r [k v]] (assoc r k (apply f v))) {} m))

When I try to call this function on my map:

(remap toydata #(Float/parseFloat %))

I get an error:

ClassCastException clojure.lang.PersistentVector cannot be cast to java.lang.String

Can anyone help?

The problem is that the (apply fv) part of remap requires f to be a multi-arity function. I would change remap to be like this:

(defn remap [m f] 
  (reduce (fn [r [k v]] (assoc r k (f v))) {} m))

and then do

(remap toydata (fn[x] 
  (if (coll? x) (into [] (map #(Float/parseFloat %) x)) (#(Float/parseFloat %) x))))

output:

{"MYCN" 5.11, "ABC9" [3.21 1.32], "EGFR" [12.34 4.45 1.32]}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM