user8067719
user8067719

Reputation:

Clojure iteration, modification and operation on nested values

I have some data that looks like this:

{2007-08-09 [{ :steaks 10 }, { :shakes  30 }, { :iced-tea 50 }],
 2007-08-10 [{ :steaks 15 }, { :shakes  09 }, { :iced-tea 57 }]}

I'm trying to iterate through these data, sum every hash and then, add a new hash containing this sum, so it would look like this:

{2007-08-09 [{ :steaks 10 }, { :shakes  30 }, { :iced-tea 50 }, {:total-orders 90}],
 2007-08-10 [{ :steaks 15 }, { :shakes  09 }, { :iced-tea 57 }, {:total-orders 81}]}

Question is: I'm totally lost at this. When i try to iterate the data using doseq and map, it won't return something like

[{ :steaks 10 }, { :shakes 30 }, { :iced-tea 50 }]

so i can add these hashes, it is returning the exact same value as before. And even if it was, i do not know how is the best way to append the new hash containing the total orders. Is it a good practice to overwrite the variable? Or is there a better way to do it? Thank you very much.

Upvotes: 0

Views: 98

Answers (1)

slipset
slipset

Reputation: 3078

So, cleaning up your data structure a bit, you get

(def orders {"2007-08-09" [{ :steaks 10 }, { :shakes  30 }, { :iced-tea 50 }],
 "2007-08-10" [{ :steaks 15 }, { :shakes  09 }, { :iced-tea 57 }]})

I don't know why you chose to make your orders as individual hash-maps and not a hash map as such

(def orders {"2007-08-09" {:steaks 10 :shakes  30 :iced-tea 50 },
 "2007-08-10" {:steaks 15 :shakes  09 :iced-tea 57 }})

So, you want the total for a day, this is done by (with your data structure)

(def orders-pr-day [{ :steaks 10 }, { :shakes  30 }, { :iced-tea 50 }])

 (->> orders-pr-day 
     (into {})   ;; I want it as a hash map
     vals        ;; pull out the values e.g. 10, 30 50
     (reduce +)) ;; sum it up

Then you can make a function which sums up a given day and adds the total:

(defn sum-day [[date orders-pr-day]] ; we can restructure a map-entry 
  [date (conj orders-pr-day {:total (->> orders-pr-day
                                    (into {})
                                    vals
                                    (reduce +))})])

And then finally, you map over your data and stick it in a map

(into {} (map sum-day orders))

This also outlines my way of solving this problem. Tackle the calculations on one thing first, then compose your way to a total solution. One could argue that

(->> orders-pr-day (into {}) vals (reduce +))

deserves to be a function, but YMMV.

Upvotes: 1

Related Questions