объединить карту и список векторов и списков

У меня есть две структуры данных:

(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")))

Некоторые могут признать это данными JIRA. Однако я хочу объединить эти две структуры, чтобы они выглядели так:

; 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") )}
            ])

Итак, после выполнения функций я хочу, чтобы результат выглядел так:

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

У меня возникли проблемы с объединением и сопоставлением двух структур, чтобы получить мой результат, и я хотел бы получить несколько советов о том, как подойти к этой проблеме в clojure :-)

Спасибо, Свен

Обновление: поскольку неясно, какими должны быть x и y, я попытаюсь объяснить их немного подробнее. Предполагается, что x — это дата с начальным значением сегодняшнего дня, и на каждом шаге итерации к ней будет добавляться сторипойнт эпоса «ARP-37» — это эпос, а 8.0 — его сторипойнт. y чем-то похож, поскольку он начинается с некоторых из всех сюжетных точек эпического списка, а затем на каждом шаге итерации уменьшается количество сюжетных точек своего эпоса. Итерация будет по списку эпиков.


person sveri    schedule 18.02.2014    source источник


Ответы (2)


Я использовал reductions, чтобы получить кумулятивные значения по мере того, как мы уменьшаем ваш ввод.

Входные данные получены из списка эпиков с использованием map.

Я использую несколько простых преобразований типов, чтобы получить правильные приращения и типы вывода.

(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})
person noisesmith    schedule 18.02.2014
comment
Это довольно круто :-) Я не знал о функции сокращения, спасибо за понимание. - person sveri; 19.02.2014

Я не знаком с данными JIRA, но мне не совсем понятно, что должна содержать ваша желаемая структура данных. Какими должны быть x и y?

В общем, подход, который вы бы использовали для объединения двух или более структур данных и создания одной структуры данных в другой форме, заключается в том, чтобы мыслить с точки зрения последовательных упрощений. Сначала попробуйте объединить две структуры любым возможным способом, который связывает соответствующие поля с подходящим ключом (уменьшение одной или другой структуры, передача пустой карты в качестве начального значения будет хорошей отправной точкой). Если у вас есть одна структура данных в форме, которая вам не нужна, пропустите ее через карту или снова уменьшите, чтобы получить что-то более простое. Повторяйте, пока не получите то, что хотите. Если ваше окончательное решение слишком сложное, убедитесь, что оно протестировано, и посмотрите на рефакторинг сейчас, когда оно работает.

person d11wtq    schedule 18.02.2014
comment
Привет, я добавил обновление, которое, надеюсь, сделает это более понятным. Я уже пытался шаг за шагом приближаться к решению, но последние несколько часов мне это не удалось, спасибо, что снова меня мотивировали, я попробую еще раз завтра :-) - person sveri; 19.02.2014