Reputation: 8497
Is there a simple way to convert a list of key-values into a map while also renaming the keys in a conditional way?
Example:
[{:count 4, :happened "true"} {:count 1, :happened "false"}]
converted into:
{:happened-count: 4, :didnt-happen-count: 1}
I'm kinda close:
user=> (def foo [{:count 4, :happened "true"} {:count 1, :happened "false"}])
user=> (into {} (map (juxt :happened :count) foo))
{"true" 4, "false" 1}
edit: This works, but it is ugly. Hoping for something nicer:
(clojure.set/rename-keys (into {} (map (juxt :happened :count) foo)) {"true" :happened-count "false" :didnt-happen-count})
Upvotes: 0
Views: 132
Reputation: 29976
There are a million ways to approach a problem like this. I like to be explicit about the steps. Here is how I would think about it:
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test))
(dotest
(let [data [{:count 4, :happened "true"}
{:count 1, :happened "false"}
{:count 5, :happened "true"}
{:count 3, :happened "false"}]
data-split (group-by :happened data)
sum-count (fn [recs]
(reduce +
(mapv :count recs)))
result {:happened-num (sum-count (get data-split "true"))
:didnt-happen-num (sum-count (get data-split "false"))}]
(is= data-split
{"true" [{:count 4, :happened "true"}
{:count 5, :happened "true"}],
"false" [{:count 1, :happened "false"}
{:count 3, :happened "false"}]} )
(is= result {:happened-num 9, :didnt-happen-num 4})))
I added multiple records for the true & false cases, as I that seems like a more typical use case.
Upvotes: 1
Reputation: 17859
i would rather advice using simple reduction
(def mapping {"true" :happened-count "false" :didnt-happen-count})
(reduce #(assoc % (-> %2 :happened mapping) (:count %2)) {} data)
;;=> {:happened-count 4, :didnt-happen-count 1}
Upvotes: 3
Reputation: 3346
If it helps, you can use the ->>
macro to see the transformation as a pipeline:
(->> [{:count 4, :happened "true"} {:count 1, :happened "false"}]
(map (juxt :happened :count))
(into {})
(clojure.set/rename-keys {"true" :happened-count
"false" :didnt-happen-count}))
eg. first extract the values, then group them into a new map, then rename the keys
Upvotes: 2