1

我有一系列地图。

;; 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))

我想在我工作的时候把它扔给社区。如果我在这里走错了路,请告诉我。

4

2 回答 2

5

如果我正确理解了意图,您将按:customer 分组,然后将操作向量包装到: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 {}))
于 2012-06-27T04:55:38.303 回答
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.

于 2012-06-27T05:57:34.980 回答