clojure - 计算向量内的hashmap中的出现次数

时间:2018-03-28 21:58:36

标签: clojure

给出以下向量:

[{:id "1" :performed [{:type "typeA"}, {:type "typeA"}, {:type "typeB"}]}, 
 {:id "2" :performed [{:type "typeB"}, {:type "typeB"}, {:type "typeB"}]}

如何计算已执行类型的出现次数?

预期产出:

[{:id "1" :typeA 2 :typeB 1}, {:id "2" :typeB "3"}]

2 个答案:

答案 0 :(得分:1)

括号在您的示例中并不完全匹配,但假设您的意思是这样的

(def data
  [{:id "1" :performed [{:type "typeA"}, {:type "typeA"}, {:type "typeB"}]}
   {:id "2" :performed [{:type "typeB"}, {:type "typeB"}, {:type "typeB"}]}])
你可以写

(mapv 
  (fn [{:keys [id performed]}]
      (->> performed
           (map (comp keyword :type))
           frequencies
           (into {:id id})))
  data)

得到这个答案:

[{:id "1", :typeA 2, :typeB 1} {:id "2", :typeB 3}]

但是,你可以考虑另一种表现形式是否能更好地为你服务。例如

(->> data
 (map (juxt :id #(->> % :performed (map :type) frequencies)))
 (into {}))

会给出结果

{"1" {"typeA" 2, "typeB" 1}, "2" {"typeB" 3}}

答案 1 :(得分:0)

您的输入不是有效的数据结构,我假设您想要一张地图矢量并将其清理干净,并确保type始终是关键字:

(def foo 
  [{:id "1" :performed [{:type "typeA"} {:type "typeA"} {:type "typeB"}]} 
   {:id "2" :performed [{:type "typeB"} {:type "typeB"}{:type "typeB"}]}])

(defn do-eet [vector-of-maps]
  (for [[id performed] 
        (map (juxt :id :performed) vector-of-maps)]
      (merge {:id id } 
             (frequencies (mapcat vals performed)))))

(do-eet foo)