GROUP BY and Aggregation on Vector of maps - Clojure

And for completeness here's an alternate version that uses map:

(map (fn [[firmAccount vals]] 
   {:firmAccount firmAccount 
    :Val (reduce + (map :Val vals)) 
    :PE (reduce + (map :PE vals))}) 
  (group-by :firmAccount a))

Try creating a new map array or map of maps with the same structure. You can write a function to add elements to this new map that sums that fields if the :firm-account exists. Maybe a map like this?

(def a {"MSFT" {:Val 25  :PE 7 }
        "GOG" {:Val 15 :PE 3} 
        "YAH" {:Val 8 :PE 1}})

With a personalized add function like:

(add-to-map [element map]
  (if (contains? (find-name element))
    {map (add-fields element (find (find-name element)))}
    {map element}))

Clojure.core has a built-in group-by function. The solution becomes a little ugly by the presence of both text and int vals in the maps.

(for [m (group-by :firmAccount a)]
   (assoc (apply merge-with + (map #(dissoc % :firmAccount) (val m)))
          :firmAccount (key m)))

Tags:

Clojure