This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-03-22
Channels
- # beginners (42)
- # boot (73)
- # cider (17)
- # clara (1)
- # cljs-dev (47)
- # cljsrn (9)
- # clojars (4)
- # clojure (241)
- # clojure-italy (11)
- # clojure-norway (5)
- # clojure-russia (93)
- # clojure-spec (28)
- # clojure-uk (32)
- # clojurescript (170)
- # core-async (20)
- # cursive (62)
- # data-science (2)
- # datomic (47)
- # dirac (4)
- # events (1)
- # funcool (12)
- # gsoc (1)
- # hoplon (59)
- # immutant (8)
- # lambdaisland (4)
- # luminus (3)
- # lumo (11)
- # off-topic (13)
- # om (81)
- # onyx (1)
- # pedestal (47)
- # planck (30)
- # re-frame (2)
- # reactive (1)
- # reagent (2)
- # ring-swagger (15)
- # rum (1)
- # slack-help (5)
- # specter (5)
- # testing (5)
- # uncomplicate (8)
- # untangled (16)
- # vim (71)
- # yada (16)
Question...Hopefully this explains is thoroughly...I know the answer to this is right in front of me but I can't for the life of me think of what it is.
(def events [{:action "play" :value 3}
{:action "stop" :value 4}]
{:action "rewind" :value 1}])
(def original-map {:value 500})
(defn do-thing [original-map events]
; when event is 'play', add :value from event to the value in original-map
; when event is 'stop', add :value from event to the value in the original-map
; when event is 'rewind', subtract :value from event to the value in the original-map
; expected result {:value 506}
)
So, I want (do-thing)
to go through the collection of events and check to see what their action is. Once it see's play
, it adds its value to original-map
's value. It should then move onto the next event. In the event that :action
is stop
, it should add it's value to original-map
's value.
The expected result should be {:value 507}
. I know I could just take the values from both events, add them up and add them to the original-map value. But that's not an option. I'm trying to go through the events and perform actions with them accordingly.@byron-woodfork For a start you’re defining do-thing as a vector with two elements, I assume you want it to be a function?
whoops, yeah. I'll edit.
@xsyn @drayah Yup. There would be multiple actions and events. I can extend the example code to reflect that. I started to but was trying to keep things as simple as possible.
@byron-woodfork Why I’m struggling is that I’m expecting to see a conditional of sorts, but I don’t really understand what that conditional looks like, because in both examples you’ve provided it’s the same thing
@xsyn Yup. I see why that's confusing. I added an extra option. rewind
. So when the action is rewind, it should instead subtract the value and not add.
Does that clear things up at all?
this is some pretty ugly code and needs to be cleaned up, but how about?
(defn do-thing
[o-map evts]
(reduce (fn [acc e]
(cond
(= (:action e) "play") {:value (+ (:value acc) (:value e))} ; when play
(= (:action e) "stop") {:value (+ (:value acc) (:value e))} ; when stop
:else {:value (:value acc)}; when anything else
)) o-map evts))
Hmmmmm. I'll have to experiment with that. It looks like the direction I was headed though.
Oh, that’s interesting, I thought it need to recur on itself until something changed, or it ran out of events
@xsyn that's another route I was considering as well. I think it could be solved either way honestly.
The recur option seemed right. But I kept confusing myself when thinking about removing events from the collection so the same events wouldn't be hit twice.
@byron-woodfork My version:
(defn do-thing [original-map events]
(reduce (fn [acc-map {:keys [action value]}]
(if (#{"play" "stop"} action) (update acc-map :value + value) acc-map))
original-map
events))
Agreed, I don't think I've ever seen that syntax though. Is there a name for it?
it’s a hash-set literal, hash-sets when called as functions call get
For more information https://clojure.org/reference/data_structures#Sets
as do hash-maps, vectors, keywords, and symbols
Ah cool
([1 2 3] 2)
interesting, so hash-set literals return the value if it’s in the set, but vectors called as a function return the value at that index?
camdenclark right - because hash-set can be thought of as a mapping from item to itself
(and is often implemented that way, I forget if clojure does that though)
or, another way to put it, hash-set implements get as “the value, if present in this set” and all associative clojure data types implement call as get
I see. ((into #{} '(1 2 3)) 2) doesn’t work on /src, what’s up with that?
It works in my repl
why use (into #{} ‘(1 2 3)) instead of #{1 2 3} ? (or (into #{} [1 2 3]) at least)
I was just curious if it would work, I’m just playing around with the syntax (very new to functional programming and clojure)
oh, right, so all hash-sets work that way, whether or not defined as literals
is that the preferred way in clojure to assert that a value is inside a vector? Turn it into a hash-set and get?
for a vector, it only looks up by index
there’s index-of to see if it is present
err. .indexOf - I wonder why I thought index-of worked
@noisesmith Excellent! Thanks
@noisesmith clojure.string/index-of
exists (as of 1.8).
(but not for non-strings)
@seancorfield ahh, that's clearly the one I was thinking of, thanks