Card casting values ​​for their correct types in clojure

I am parsing a CSV file, and since the CSV does not have type information, all values ​​(float, ints, date, etc.) become strings. To fix the types, I created a map that defines each type of field. Now I need to convert the fields to the appropriate types.

Given a map where the values ​​are strings containing integers and floats and possibly other types, I need to return a map with the values ​​that were converted to their corresponding types by referencing the type definition map. Below is a sample code that I came up with, but I believe there should be a better way to do this.

(mapv #(case ({"one" :int, "point-two" :float} (key %)) :int {(key %) (Integer/parseInt (val %))} :float {(key %) (Float/parseFloat (val %))} {(key %) (val %)}) ; If there no type defined, just return the original {"one" "1", "point-two" ".2", "three" "three"}) 

By re-creating the map in each case, the result is needed, it seems that there should be a way to simply change the values ​​without touching the keys inside the case . Re-creating a map entry using {(key %) (val %)} for the default test seems even more inconvenient.

+4
source share
1 answer

You can use reduce-kv and update-in .

 (def input {:a "1" :b "2.5" :c "more" :d "string" :e "keys"}) (def typetrans {:a #(Long/parseLong %) :b #(Double/parseDouble %)}) (reduce-kv #(update-in %1 [%2] %3) input typetrans) ; => {:a 1, :c "more", :b 2.5, :d "string", :e "keys"} 

It applies only to keys that really need to be changed. Not the whole map.

+3
source

Source: https://habr.com/ru/post/1496723/


All Articles