Try if-some: https://clojuredocs.org/clojure.core/if-some
On Mon, May 25, 2015 at 4:07 PM, <lawre...@waleup.com> wrote: > > I started to write an essay, aimed at those programmers who are > experienced with highly mutable languages such as Javascript, Ruby, PHP, > etc, to demonstrate how one's code style changes when one switches to a > mostly immutable language such as Clojure. However, my Clojure code is not > nearly as terse as I wanted. In particular, I have this nil check: > > (if (nil? ((:winner c) nu)) > (assoc nu (:winner c) {:history [{}]}) > nu) > > which I assume I am writing because I am ignorant. I'm guessing there > might be something clever I can do to avoid this? > > For my code examples, I'm working with these 2 data structures: > > (def users { > :henry { > :history > [ > {:housing 25, :restaurants 40, :theater 930}, > {:restaurants 30, :crisis 220} > ] > }, > :lisa { > :history > [ > {:theater 80}, > {:housing 445, :restaurants 15, :theater 35} > ] > }, > :pasha { > :history > [ > {:restaurants 5}, > {:restaurants 40, :theater 60} > ] > }, > :eli { > :history > [ > {:crisis 135, :restaurants 440, :theater 65}, > {:theater 95} > ] > } > }) > > (def contests [{:category :housing, :prize-money 100, :winner :eli}, > {:category :housing, :prize-money 30, :winner :henry}, > {:category :housing, :prize-money 340, :winner :henry}, > {:category :housing, :prize-money 45, :winner :susan}, > {:category :housing, :prize-money 15, :winner :henry}, > {:category :housing, :prize-money 10, :winner :pasha}, > {:category :housing, :prize-money 25, :winner :pasha}, > {:category :crisis, :prize-money 100, :winner :eli}, > {:category :crisis, :prize-money 2330, :winner :henry}, > {:category :crisis, :prize-money 90, :winner :henry}, > {:category :restaurants, :prize-money 1130, :winner :eli}, > {:category :restaurants, :prize-money 130, :winner :pasha}, > {:category :theater, :prize-money 60, :winner :eli}, > {:category :theater, :prize-money 90, :winner :pasha}, > {:category :theater, :prize-money 130, :winner :pasha}, > {:category :theater, :prize-money 830, :winner :susan}, > {:category :theater, :prize-money 90, :winner :susan}, > {:category :theater, :prize-money 270, :winner :eli}]) > > Presumably "users" shows past winnings from 2 rounds of some contest, > whereas "contests" shows the winnings from the 3rd round, which need to be > added to "users". So I wrote: > > > (defn add-placeholder-to-history [us] > (loop [u us nu {}] > (if (first u) > (recur > (rest u) > (assoc nu (get (first u) 0) {:history (into [] (cons {} > (:history (get (first u) 1))))})) > nu))) > > (defn update-history [nu c] > (update-in > (if (nil? ((:winner c) nu)) > (assoc nu (:winner c) {:history [{}]}) > nu) > [(:winner c) :history 0 (:category c)] (fnil #(+ %1 (:prize-money > c)) 0))) > > And so in the end we would simply call: > > (reduce > update-history > (add-placeholder-to-history users) > contests) > > Which correctly gives me: > > { > :susan { > :history [{:theater 920, :housing 45}] > } > :lisa { > :history [{} > {:theater 80} > {:housing 445, :restaurants 15, :theater 35}] > } > :henry { > :history [{:crisis 2420, :housing 385} > {:housing 25, :restaurants 40, :theater 930} > {:crisis 220, :restaurants 30}] > } > :eli { > :history [{:theater 330, :restaurants 1130, :crisis 100, :housing 100} > {:crisis 135, :restaurants 440, :theater 65} > {:theater 95}] > } > :pasha { > :history [{:theater 220, :restaurants 130, :housing 35} > {:restaurants 5} > {:restaurants 40, :theater 60}] > } > } > > And then I wrote: > > ----------------------------------- > > By the way, you might be wondering what this is for: > > (if (nil? ((:winner c) nu)) > (assoc nu (:winner c) {:history [{}]}) > nu) > > We do this for Susan. She is a new contestant who won some money in the > newest round of contests, however, she does not yet exist in "users", so we > need to create a space for her. Without these 3 lines of code, we get this > for her: > > {:susan {:history {0 {:theater 920, :housing 45}}}, > > But with these 3 lines of code, we get the correct results for her, and > for everyone else. > > ----------------------------------- > > I am wondering if I can avoid those 3 lines of code? > > > > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- “One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.” (Robert Firth) -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.