Question

I have two datastructures:

(def epics {"ARP-37" 8.0, "ARP-24" 5.0, "ARP-22" 13.0, "ARP-6" 21.0, "ARP-1" 8.0})
(def releases '(["Release one" '("ARP-37" "ARP-22" "ARP-6")]))
; gets the sum of a list of epics (maps epic keys to its corresponding story points)
(defn get-max-sp [epic-list] (reduce + (map #(get epics %) epic-list)))
(def initial-sp (get-max-sp '("ARP-37" "ARP-22" "ARP-6")))

Some might recognize this as JIRA data. However, I want to combine these two structures to look like this:

; where (now) is a function from clj-time returning the current date
(def result [{x: (now), y: initial-sp }
             {x: (+ now (get epics "ARP-37")), y: (- initial-sp (get epics "ARP-37))}
             {x: (+ now (get epics "ARP-37") (get epics "ARP-22")), 
                  y: (- initial-sp (get epics "ARP-37") (get epics "ARP-22"))}
             {x: (+ now (get epics "ARP-37") (get epics "ARP-22")
                     (get epics "ARP-6")), 
                  y: (- initial-sp (get epics "ARP-37") (get epics "ARP-22")
                       (get epics "ARP-6") )}
            ])

So, after executing the functions I want the result to look like this:

[{x: 2014-02-18, y: 42}
 {x: 2014-02-26, y: 34}
 {x: 2014-03-11, y: 21}
 {x: 2014-04-01, y: 0}
 ]

I have trouble combining and mapping the two structures to get my result and I would love to get some hints on how to approach that problem in clojure :-)

Thanks, Sven

Update: As it seems to be unclear what x and y should be i will try to explain them a bit more. x is supposed to be a date with an initial value of today and on every iteration step the storypoint of an epic will be added to it "ARP-37" is the epic and 8.0 its storypoint. y is something similar as it starts with the some of all the story points of the epic list and then goes down on every iteration step the number of story points of its epic. The iteration will be over the list of epics.

Was it helpful?

Solution

I used reductions to get the cumulative values as we reduce across your input.

The input is derived from the list of epics using a map.

I use some simple type conversions to get the proper increments and output types.

(let [add-days (fn [d days]
                 (java.util.Date. (long (+ (.getTime d)
                                           (* 1000 60 60 24 days)))))
      initial {:x (java.util.Date.)
               :y 42}
      our-epics ["ARP-37" "ARP-22" "ARP-6"]]
  (reductions (fn [tally epic-n]
                {:x (add-days (:x tally) epic-n)
                 :y (long (- (:y tally) epic-n))})
              initial
              (map #(get epics %)
                   our-epics)))

({:x #inst "2014-02-18T22:31:17.027-00:00", :y 42}
 {:x #inst "2014-02-26T22:31:17.027-00:00", :y 34}
 {:x #inst "2014-03-11T22:31:17.027-00:00", :y 21}
 {:x #inst "2014-04-01T22:31:17.027-00:00", :y 0})

OTHER TIPS

I'm not familiar with JIRA data, but I'm not entirely clear on what your wanted data structure is supposed to contain. What are x and y supposed to be?

In general the approach you'd take to combine two or more data structures and produce a single data structure in a different shape is to think in terms of consecutive simplifications. First try to merge the two structures in any way you can that associates relevant fields on a suitable key (a reduce over one or the other structure, passing in an empty map as the initial value would be a good starting point). Once you have a single data structure in the shape you don't want, pass that through a map or reduce again to get something simpler. Repeat until you have what you want. If your final solution is too complex, make sure it's tested and look at refactoring now that it works.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top