在哈希映射中用零替换nil值

时间:2013-04-18 16:12:03

标签: clojure hashmap null

我在clojure中有一个包含一些nil值的哈希映射。我试图对数据进行分组并对值求和,由于nil值,这给了我一个空指针。有人可以建议我如何迭代哈希映射并用整数0替换所有的nil值?

(def data [{:MEDAL "SILVER" :EMEA 1 :NA nil :ASPAC 3}
       {:MEDAL "GOLD" :EMEA 1 :NA 2 :ASPAC 3}
       {:MEDAL "GOLD" :EMEA nil :NA 2 :ASPAC nil}
       {:MEDAL "BRONZE" :EMEA nil :NA 2 :ASPAC 3}
       {:MEDAL "SILVER" :EMEA 1 :NA 2 :ASPAC 3}
       {:MEDAL "GOLD" :EMEA 1 :NA nil :ASPAC nil}
       {:MEDAL "BRONZE" :EMEA 1 :NA 2 :ASPAC 3}])

由于

5 个答案:

答案 0 :(得分:1)

您可以考虑使用keep来处理它们,而不是用零替换nil值。例如:

(apply + (keep :NA data))
; 10
(apply + (keep (fn [m] (when (= (:MEDAL m) "SILVER") (:EMEA m))) data))
; 2

答案 1 :(得分:0)

(map (fn [m]
       (into {} 
         (map (fn [[k v]]
              [k (if (nil? v) 0 v)]) m)))
     data)
=> ({:EMEA 1, :NA 0, :MEDAL "SILVER", :ASPAC 3} 
    {:EMEA 1, :NA 2, :MEDAL "GOLD", :ASPAC 3} 
    {:EMEA 0, :NA 2, :MEDAL "GOLD", :ASPAC 0} 
    {:EMEA 0, :NA 2, :MEDAL "BRONZE", :ASPAC 3} 
    {:EMEA 1, :NA 2, :MEDAL "SILVER", :ASPAC 3} 
    {:EMEA 1, :NA 0, :MEDAL "GOLD", :ASPAC 0}
    {:EMEA 1, :NA 2, :MEDAL "BRONZE", :ASPAC 3})

答案 2 :(得分:0)

您可以使用fnil

(->> data
  (apply merge-with conj (zipmap [:EMEA :NA :MEDAL :ASPAC] (repeat [])))
  (reduce-kv #(assoc %1 %2 (reduce (fnil + 0 0) 0 %3)) {}))

显然:MEDAL需要其他治疗。

答案 3 :(得分:0)

我假设您要按以下方式对数据进行分组:MEDAL然后添加EMEA,ASPAC等,对吗?

;; Helper function
(defn batch-hashmaps
  "Applies operation on values of keys in maps. filterf filters valid values.
Example: (batch-hashmaps + [:b :c] number? {:a 30, :b 50, :c :cheese} {:b 30, :c 40})
=> {:b 80, :c 40}"
  [operation keys filterf & maps]
  (apply conj {} 
          (for [key keys]
            [key (apply operation (filter filterf (map #(key %) maps)))])))

(for [medal (set (map #(:MEDAL %) data))]
  (assoc (apply (partial batch-hashmaps + [:EMEA :NA :ASPAC] number?) (filter #(= medal (:MEDAL %)) data) ) :MEDAL medal))

这应该是理想的结果:

({:MEDAL "GOLD", :EMEA 2, :NA 4, :ASPAC 3}
{:MEDAL "SILVER", :EMEA 2, :NA 2, :ASPAC 6}
{:MEDAL "BRONZE", :EMEA 1, :NA 4, :ASPAC 6})

答案 4 :(得分:0)

这是另一个快速而又脏的东西。

(defn sum-medal
[medal data]
(assoc (apply (partial merge-with (fn [& [_ _ :as vals]] (apply + (filter number? vals)))) (filter #(= (:MEDAL %) medal) data)) :MEDAL medal))