Elie Ladias
Elie Ladias

Reputation: 83

Clojure, transform collection to map

I was wondering what was the best way to iterate over many collection to create a map in clojure. Actually i have 3 collection:

("Aujourd'hui" "Demain" "25.11" "26.11" "27.11" "28.11" "29.11") 
("2 °C" "2 °C" "1 °C" "0 °C" "-3 °C" "-4 °C" "0 °C") 
("8 °C" "6 °C" "4 °C" "2 °C" "1 °C" "1 °C" "5 °C")

And i like to create a collection of maps looking like this:

{:date Aujourd'hui :temp-min 2°C :temp-max 8°C}{...}

And know it should not be so difficult but I can't figure out how to do that right.

Thanks for your help !

Upvotes: 0

Views: 612

Answers (2)

Thumbnail
Thumbnail

Reputation: 13473

The following function constructs a table as a sequence of records from column heading titles and sequence of columns:

(defn build-table [titles columns]
  (apply map (fn [& xs] (zipmap titles xs)) columns))

There should be as many :titles as there are columns.

For example,

(build-table [:date :temp-min :temp-max] data)

where

(def data ['("Aujourd'hui" "Demain" "25.11" "26.11" "27.11" "28.11" "29.11") 
           '("2 °C" "2 °C" "1 °C" "0 °C" "-3 °C" "-4 °C" "0 °C")
           '("8 °C" "6 °C" "4 °C" "2 °C" "1 °C" "1 °C" "5 °C")])

... produces

 ({:temp-max "8 °C", :temp-min "2 °C", :date "Aujourd'hui"}
  {:temp-max "6 °C", :temp-min "2 °C", :date "Demain"}
  {:temp-max "4 °C", :temp-min "1 °C", :date "25.11"}
  {:temp-max "2 °C", :temp-min "0 °C", :date "26.11"}
  {:temp-max "1 °C", :temp-min "-3 °C", :date "27.11"}
  {:temp-max "1 °C", :temp-min "-4 °C", :date "28.11"}
  {:temp-max "5 °C", :temp-min "0 °C", :date "29.11"})

This leaves all the data elements as strings. Converting them to numbers, preferably with units attached, can be tackled independently. As they are written, such as 2°C are not valid Clojure.

Upvotes: 1

noisesmith
noisesmith

Reputation: 20194

We can use map to construct a hash-map for each index of the collections. When provided with more than two arguments, map moves through all the collections in parallel.

user> (let [dates '("Aujourd'hui" "Demain" "25.11" "26.11" "27.11" "28.11" "29.11") 
            mins '("2 °C" "2 °C" "1 °C" "0 °C" "-3 °C" "-4 °C" "0 °C") 
            maxes '("8 °C" "6 °C" "4 °C" "2 °C" "1 °C" "1 °C" "5 °C")]
        (pprint (map #(hash-map :date %1 :temp-min %2 :temp-max %3) dates mins maxes)))
({:date "Aujourd'hui", :temp-max "8 °C", :temp-min "2 °C"}
 {:date "Demain", :temp-max "6 °C", :temp-min "2 °C"}
 {:date "25.11", :temp-max "4 °C", :temp-min "1 °C"}
 {:date "26.11", :temp-max "2 °C", :temp-min "0 °C"}
 {:date "27.11", :temp-max "1 °C", :temp-min "-3 °C"}
 {:date "28.11", :temp-max "1 °C", :temp-min "-4 °C"}
 {:date "29.11", :temp-max "5 °C", :temp-min "0 °C"})

Upvotes: 3

Related Questions