我有一系列地图。
;; input
[{:country "MX", :video 12345, :customer "cid1"}
{:country "US", :video 12345, :customer "cid2"}
{:country "MX", :video 54321, :customer "cid1"}]
我想将其转换为多图。我想生成。
;; output
{"cid1"
{:actions
[{:country "MX", :video 12345, :customer "cid1"}
{:country "MX", :video 12345, :customer "cid1"}]},
"cid2"
{:actions
[{:country "US", :video 12345, :customer "cid2"}]}}
我觉得我应该使用update-in
。有些事情......我只是没有确切地知道some-fn-here
的样子,我认为其他人可能有同样的问题。
(defn add-mm-entry
[m e]
(update-in m [(:customer e)] some-fn-here))
(def output (reduce add-mm-entry {} input))
想在我工作的时候,我会把它扔给社区。如果我走错了路,请告诉我。
答案 0 :(得分:5)
如果我正确理解了意图,那么您将按以下方式进行分组:客户然后将操作向量包装到:actions。您可以使用 clojure.core / group-by 进行分组,然后映射( clojure.core / map )结果:
(def v [{:country "MX", :video 12345, :customer "cid1"}
{:country "US", :video 12345, :customer "cid2"}
{:country "MX", :video 54321, :customer "cid1"}])
(->> v
(group-by :customer)
(map (fn [[cid xs]] {cid {:actions xs}}))
(into {}))
答案 1 :(得分:2)
group-by
是否适用于我的特定情况。我没有对它进行测试,但我认为这种方法会减少中间产品。
(def v [{:country "MX", :video 12345, :customer "cid1"}
{:country "US", :video 12345, :customer "cid2"}
{:country "MX", :video 54321, :customer "cid1"}])
(defn add-entry
[m e]
(let [cust (:customer e)]
(update-in m [cust :actions] #(conj % e))))
(reduce add-entry {} v)
仍会导致加载完整数据集,但它会直接加载到目标数据结构中,而不是加载到地图矢量中,然后加载到多图中。同样,我还没有测试过检查哪一个确定性能更高,但看起来这个对数据集的迭代次数减少了一半,并且避免了创建来自group-by
的不需要的地图矢量。