对嵌套值进行Clojure迭代,修改和操作

时间:2017-05-26 05:11:24

标签: clojure

我有一些看起来像这样的数据:

{2007-08-09 [{ :steaks 10 }, { :shakes  30 }, { :iced-tea 50 }],
 2007-08-10 [{ :steaks 15 }, { :shakes  09 }, { :iced-tea 57 }]}

我试图遍历这些数据,对每个哈希求和,然后添加一个包含此总和的新哈希,所以它看起来像这样:

{2007-08-09 [{ :steaks 10 }, { :shakes  30 }, { :iced-tea 50 }, {:total-orders 90}],
 2007-08-10 [{ :steaks 15 }, { :shakes  09 }, { :iced-tea 57 }, {:total-orders 81}]}

问题是:我完全迷失了。当我尝试使用 doseq 地图迭代数据时,它不会返回类似

的内容
  

[{:steaks 10},{:shakes 30},{:iced-tea 50}]

所以我可以添加这些哈希值,它返回的值与以前完全相同。 即使它是,我不知道如何附加包含总订单的新哈希的最佳方法。覆盖变量是一个好习惯吗?或者有更好的方法吗?非常感谢你。

1 个答案:

答案 0 :(得分:1)

所以,稍微清理一下你的数据结构,你得到了

(def orders {"2007-08-09" [{ :steaks 10 }, { :shakes  30 }, { :iced-tea 50 }],
 "2007-08-10" [{ :steaks 15 }, { :shakes  09 }, { :iced-tea 57 }]})

我不知道你为什么选择将订单作为单独的哈希映射而不是哈希映射

(def orders {"2007-08-09" {:steaks 10 :shakes  30 :iced-tea 50 },
 "2007-08-10" {:steaks 15 :shakes  09 :iced-tea 57 }})

所以,你想要一天的总数,这是通过(使用你的数据结构)来完成的

(def orders-pr-day [{ :steaks 10 }, { :shakes  30 }, { :iced-tea 50 }])

 (->> orders-pr-day 
     (into {})   ;; I want it as a hash map
     vals        ;; pull out the values e.g. 10, 30 50
     (reduce +)) ;; sum it up

然后你可以创建一个总结给定日期的函数并添加总数:

(defn sum-day [[date orders-pr-day]] ; we can restructure a map-entry 
  [date (conj orders-pr-day {:total (->> orders-pr-day
                                    (into {})
                                    vals
                                    (reduce +))})])

最后,您将数据映射并将其粘贴在地图中

(into {} (map sum-day orders))

这也概括了我解决这个问题的方法。首先解决一件事的计算,然后编写一个完整的解决方案。 人们可以争辩说

(->> orders-pr-day (into {}) vals (reduce +))

应该是一个功能,但是YMMV。