Как добавить ключи на карту / создать ключи в текущей карте clojure
У меня есть следующая карта из запроса на получение
:form-params {"qu" ["2015 Q2" "2015 Q3" "2015 Q4" "2015 Q2"
"2015 Q3" "2015 Q4" "2015 Q2" "2015 Q3"
"2015 Q4" "2015 Q2" "2015 Q3" "2015 Q4"],
"sh" ["2580" "2580" "2580" "2983"
"2983" "2983" "53" "53"
"53" "4558" "4558" "4558"],
"prin" ["191" "191" "191" "191"
"191" "191" "191" "191"
"191" "191" "191" "191"],
"bu" ["" "" "" "" "" "" "" "" "" "" "" ""]}
Я хотел бы создать ключи:quar,:sh,:prin и:bu. Причина в том, что отсюда я собирался разделить на 4 группы и чередовать, как показано ниже
(let [params (:form-params request)
data (partition 4 (interleave (:quarter params) (:shiptoid params)
(:principalid params) (:budget params)
))
Спасибо!
1 ответ
Встроенная функция clojure.set/rename-keys
будет делать это хорошо, хотя, как и все вещи в clojure, есть несколько подходов. Итак, давайте пройдемся по процессу. То, что у вас есть, очень близко к работе. Если я просто посмотрю каждый по его оригинальному строковому ключу, мы увидим, как он работает:
user> (def request {:form-params {"qu" ["2015 Q2" "2015 Q3" "2015 Q4" "2015 Q2"
"2015 Q3" "2015 Q4" "2015 Q2" "2015 Q3"
"2015 Q4" "2015 Q2" "2015 Q3" "2015 Q4"],
"sh" ["2580" "2580" "2580" "2983"
"2983" "2983" "53" "53"
"53" "4558" "4558" "4558"],
"prin" ["191" "191" "191" "191"
"191" "191" "191" "191"
"191" "191" "191" "191"],
"bu" ["" "" "" "" "" "" "" "" "" "" "" ""]}})
#'user/request
user> (let [params (:form-params request)
data (partition 4 (interleave (params "qu") (params "sh")
(params "prin") (params "bu")))]
(clojure.pprint/pprint data))
(("2015 Q2" "2580" "191" "")
("2015 Q3" "2580" "191" "")
("2015 Q4" "2580" "191" "")
("2015 Q2" "2983" "191" "")
("2015 Q3" "2983" "191" "")
("2015 Q4" "2983" "191" "")
("2015 Q2" "53" "191" "")
("2015 Q3" "53" "191" "")
("2015 Q4" "53" "191" "")
("2015 Q2" "4558" "191" "")
("2015 Q3" "4558" "191" "")
("2015 Q4" "4558" "191" ""))
теперь это звучит так, будто вам нужна карта, которая похожа на первую карту, за исключением того, что она имеет разные ключи, указывающие на одинаковые значения. Для этого мы можем легко и эффективно создать новую карту, используя литерал карты:
user> (def new-request
(let [params (:form-params request)]
{:form-params {:quarter (params "qu")
:shiptoid (params "sh")
:principalid (params "prin")
:budget (params "bu")}}))
#'user/new-request
user> (let [params (:form-params new-request)
data (partition 4 (interleave (:quarter params) (:shiptoid params)
(:principalid params) (:budget params)))]
(clojure.pprint/pprint data))
(("2015 Q2" "2580" "191" "")
("2015 Q3" "2580" "191" "")
("2015 Q4" "2580" "191" "")
("2015 Q2" "2983" "191" "")
("2015 Q3" "2983" "191" "")
("2015 Q4" "2983" "191" "")
("2015 Q2" "53" "191" "")
("2015 Q3" "53" "191" "")
("2015 Q4" "53" "191" "")
("2015 Q2" "4558" "191" "")
("2015 Q3" "4558" "191" "")
("2015 Q4" "4558" "191" ""))
и чтобы сделать его более автоматическим, вы можете использовать update-in
:
user> (def new-request
(update-in request [:form-params]
(fn [params] {:quarter (params "qu")
:shiptoid (params "sh")
:principalid (params "prin")
:budget (params "bu")})))
#'user/new-request
user> (let [params (:form-params new-request)
data (partition 4 (interleave (:quarter params) (:shiptoid params)
(:principalid params) (:budget params)))]
(clojure.pprint/pprint data))
(("2015 Q2" "2580" "191" "")
("2015 Q3" "2580" "191" "")
("2015 Q4" "2580" "191" "")
("2015 Q2" "2983" "191" "")
("2015 Q3" "2983" "191" "")
("2015 Q4" "2983" "191" "")
("2015 Q2" "53" "191" "")
("2015 Q3" "53" "191" "")
("2015 Q4" "53" "191" "")
("2015 Q2" "4558" "191" "")
("2015 Q3" "4558" "191" "")
("2015 Q4" "4558" "191" ""))
начиная с clojure 1.7 (следующего выпуска на сегодня), вы также можете использовать update
функция, которая немного элегантнее. хотя это все еще можно сделать немного более элегантным, добавив библиотеку clojure.set и используя встроенный rename-keys
функция:
user> (def new-request
(update request :form-params
clojure.set/rename-keys {"qu" :quarter
"sh" :shiptoid
"prin" :principalid
"bu" :budget}))
#'user/new-request
user> (let [params (:form-params new-request)
data (partition 4 (interleave (:quarter params) (:shiptoid params)
(:principalid params) (:budget params)))]
(clojure.pprint/pprint data))
(("2015 Q2" "2580" "191" "")
("2015 Q3" "2580" "191" "")
("2015 Q4" "2580" "191" "")
("2015 Q2" "2983" "191" "")
("2015 Q3" "2983" "191" "")
("2015 Q4" "2983" "191" "")
("2015 Q2" "53" "191" "")
("2015 Q3" "53" "191" "")
("2015 Q4" "53" "191" "")
("2015 Q2" "4558" "191" "")
("2015 Q3" "4558" "191" "")
("2015 Q4" "4558" "191" ""))