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)

それでも完全なデータセットがロードされますが、マップのベクトルにロードされてからマルチマップにロードされるのではなく、ターゲットデータ構造に直接ロードされます。繰り返しますが、どちらがよりパフォーマンスが高いかをテストしたことはありませんが、データセットの繰り返しが 1 回少なくなり、group-by.

于 2012-06-27T05:57:34.980 に答える