Clojure 有条件地重命名列表中的键并转换为映射?
是否有一种简单的方法可以将键值列表转换为映射,同时以条件方式重命名键值 例如:Clojure 有条件地重命名列表中的键并转换为映射?,clojure,Clojure,是否有一种简单的方法可以将键值列表转换为映射,同时以条件方式重命名键值 例如: [{:count 4, :happened "true"} {:count 1, :happened "false"}] 转换为: {:happened-count: 4, :didnt-happen-count: 1} 我有点接近了: user=> (def foo [{:count 4, :happened "true"} {:count 1, :happened "false"}]) user=&
[{:count 4, :happened "true"} {:count 1, :happened "false"}]
转换为:
{:happened-count: 4, :didnt-happen-count: 1}
我有点接近了:
user=> (def foo [{:count 4, :happened "true"} {:count 1, :happened "false"}])
user=> (into {} (map (juxt :happened :count) foo))
{"true" 4, "false" 1}
编辑:这行得通,但很难看。希望有更好的东西:
(clojure.set/rename-keys (into {} (map (juxt :happened :count) foo)) {"true" :happened-count "false" :didnt-happen-count})
如果有帮助,可以使用->>宏将转换视为管道:
(->> [{:count 4, :happened "true"} {:count 1, :happened "false"}]
(map (juxt :happened :count))
(into {})
(clojure.set/rename-keys {"true" :happened-count
"false" :didnt-happen-count}))
首先提取值,然后将它们分组到一个新的映射中,然后重命名键。有无数种方法可以解决这样的问题。我喜欢明确说明步骤。以下是我的想法:
(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})))
我为正确和错误案例添加了多个记录,因为我认为这似乎是一个更典型的用例。我宁愿使用简单的简化建议
(def mapping {"true" :happened-count "false" :didnt-happen-count})
(reduce #(assoc % (-> %2 :happened mapping) (:count %2)) {} data)
;;=> {:happened-count 4, :didnt-happen-count 1}
重命名键不会将参数置于第一个位置吗?因此->>不起作用,但可能会像->那样?在本例中->>宏从映射列表中获取一个值,并将该值作为最后一个参数传递给映射行的下一个表单,其结果作为最后一个参数传递给into表单,其结果作为最后一个参数传递给重命名键的调用。我在电脑上测试过REPL@marathon这是对的。重命名键用作重命名键映射kmap,因此第一个参数现在被重命名。这似乎是最直接的!