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,因此第一个参数现在被重命名。这似乎是最直接的!