This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-07-15
Channels
- # admin-announcements (2)
- # beginners (93)
- # boot (34)
- # capetown (1)
- # cider (15)
- # cljs-dev (30)
- # cljsjs (9)
- # clojars (8)
- # clojure (199)
- # clojure-austin (3)
- # clojure-france (3)
- # clojure-greece (2)
- # clojure-italy (46)
- # clojure-quebec (7)
- # clojure-russia (2)
- # clojure-spec (76)
- # clojure-uk (16)
- # clojurescript (43)
- # core-async (7)
- # cursive (14)
- # data-science (1)
- # datascript (4)
- # datomic (3)
- # devcards (60)
- # editors (5)
- # funcool (5)
- # garden (3)
- # hoplon (32)
- # immutant (22)
- # jobs (1)
- # lein-figwheel (21)
- # leiningen (1)
- # mental-health (11)
- # mount (2)
- # off-topic (6)
- # om (16)
- # onyx (15)
- # re-frame (43)
- # reagent (20)
- # rum (18)
- # specter (37)
- # sql (2)
- # testing (8)
- # untangled (7)
- # yada (19)
combine the element in the following list based on item_id: [{:id -1, :item_id "2", :quantity "3"} {:id -2, :item_id "1", :quantity "2”} {:id -3, :item_id “1”, :quantity “3"]
it will be transform to [{:id -1, :item_id "2", :quantity "3"} {:id -2, :item_id "1", :quantity “5”}]
@rui.yang: I don't think this is something that you particularly need specter for. You should be able to accumulate your result using reduce.
@codonnell: thanks for the tips
If you want, you could omit the vals
and leave the result as a map of items, keyed by item_id
This is a more natural way to store items, in my opinion.
ah, I see
(def items [{:id -1, :item_id "2", :quantity "3"} {:id -2, :item_id "1", :quantity "2”} {:id -3, :item_id “1”, :quantity “3"}])
(reduce (fn [m {:keys [item_id quantity] :as item}] (if (contains? m item_id) (update-in m [item_id :quantity] #(+ % quantity)) (assoc m item_id item))) {} items)
{"2" {:id -1, :item_id "2", :quantity "3"}, "1" {:id -2, :item_id "1", :quantity "2”} {:id -3, :item_id “1”, :quantity “3"}}
You need to parse the :quantity
values to integers.
yeah, I see
that's odd
You're using nonstandard quote characters around the quantity key in your second item, which is causing the problem, I think.
=> (count items)
2
it thinks the value for :quantity
in the second item is just a long string
thank you all, save me tons of pain @madstap @codonnell
I fixed it like this:
(def items [{:id -1, :item_id "2", :quantity "3"}
{:id -2, :item_id "1", :quantity "2"}
{:id -3, :item_id "1", :quantity "3"}])
(defn str->int [s]
(Integer/parseInt s))
(reduce (fn [m {:keys [item_id quantity] :as item}]
(if (contains? m item_id)
(update-in m [item_id :quantity] #(+ % quantity))
(assoc m item_id item)))
{}
(map #(update % :quantity str->int) items))
it shouldn’t be string, it should be integer. but when UI form update values, somehow it is setting String. I think I should fix it there instead of fixing it in the transformation of map.
@rui.yang: On a side note, you could use specter to parse those :quantity
keys into integers, though it's pretty easy to do in core, as well.
=> (transform [ALL :quantity] #(Integer. %) items)
[{:id -1, :item_id "2", :quantity 3} {:id -2, :item_id "1", :quantity 2} {:id -3, :item_id "1", :quantity 3}]
@codonnell: thanks for the tip
no problem