This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-05-27
Channels
- # aleph (1)
- # beginners (48)
- # cider (34)
- # clojure (27)
- # clojure-dev (15)
- # clojure-uk (21)
- # clojurescript (27)
- # data-science (3)
- # datomic (10)
- # instaparse (30)
- # lumo (85)
- # off-topic (3)
- # perun (2)
- # portkey (24)
- # re-frame (13)
- # reagent (17)
- # ring (1)
- # shadow-cljs (77)
- # spacemacs (1)
- # test-check (3)
- # yada (4)
There is an RRB-vector library that I haven't checked the performance of myself, but intends to have good big-Oh performance on concatenating arbitrary pairs of vectors, or splitting vectors at selected points. It has a catvec
function for concatenating vectors, but only works on its own vectors, not Clojure's built-in ones: https://github.com/clojure/core.rrb-vector
That is definitely a bit off the Clojure beaten path.
It says it works on regular Clojure vectors... I benchmarked it too
user=> (require '[clojure.core.rrb-vector :as fv])
nil
user=> (def big-vec (vec (range 1000)))
#'user/big-vec
user=> (def big-fvec (fv/vec (range 1000)))
#'user/big-fvec
user=> (bench (fv/catvec ['foo] big-vec))
Evaluation count : 5483040 in 60 samples of 91384 calls.
Execution time mean : 10.801576 µs
Execution time std-deviation : 303.262627 ns
...
user=> (bench (fv/catvec ['foo] big-fvec))
Evaluation count : 5678460 in 60 samples of 94641 calls.
Execution time mean : 10.603606 µs
Execution time std-deviation : 123.580560 ns
...
OK, I did not realize that lib supported concatenation on normal Clojure vectors, too.
(me neither, until just now -- I'd never actually looked at it before, but clj -Sdeps ...
makes it so easy to play with a library that I couldn't resist 🙂 )
Can anyone advise how to compare Java objects nested in maps please? I’ve used clojure.java-time
to parse two strings into (equal) Durations, but my tests fail presumably because object identity is being compared.
I understand that I could use interop to call the equals
method of the Duration to get a value comparison, but I don’t understand how to do this when the Duration is nested in a map.
So... I have an array of maps that looks like this
[ {:tz_label "Pacific Daylight Time", :deleted false, :is_bot false, :color "757575", :real_name "slackbot", :updated 0, :name "slackbot", :presence "active" }
{:tz_label "Pacific Daylight Time", :deleted false, :is_bot false, :color "757575", :real_name "Some User", :updated 0, :name "some_user", :presence "away" } ]
I want to get only the maps that contain :presence "active"
Stuff like
(into {} (filter #(-> % val (= "active"))
(zipmap (map :real_name (get (clj-slack.core/slack-request connection "users.list" {"presence" "1"}) :members)) (map :presence (get (clj-slack.core/slack-request connection "users.list" {"presence" "1"}) :members)))
))
is ugly...Also
(map (juxt :real_name :presence) (get (clj-slack.core/slack-request connection "users.list" {"presence" "1"}) :members))
Close, but not really.Ah, nice. I also found the matching-entries
function
https://codereview.stackexchange.com/questions/59272/writing-filter-with-one-or-more-comparison-values
It should work! You can even skip the = true
part since the result will be truthy anyway
Doing something wrong...
(count (filter (fn [user] (= "active" (:presence user)) (not (:is_bot user)) ) ((clj-slack.core/slack-request connection "users.list" {"presence" "1"}) :members))
This works
(matching-entries ((clj-slack.core/slack-request connection "users.list" {"presence" "1"}) :members) :presence "active" :is_bot false)
CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(/tmp/form-init6285822146552374847.clj:1:16
(count (filter (fn [user] (= "active" (:presence user)) and (not (:is_bot user)) ) ((clj-slack.core/slack-request connection "users.list" {"presence" "1"}) :members)))
Damn
user=> (filter (fn [user] (and (= "active" (:presence user)) (not (:is_bot user)) ) ((clj-slack.core/slack-request connection "users.list" {"presence" "1"}) :members)))
#object[clojure.core$filter$fn__5610 0x5aa6cbba "clojure.core$filter$fn__5610@5aa6cbba"]
@overde You don't seem to have a quote for your macro body...?
Macros don't evaluate their arguments -- so b
is literally the unevaluated form (-> c :name)
.
I think you want
(defmacro branch?
"Validate if the branch is actionable"
[b & body]
`(cond (= ~b "develop") ~@body
(= ~b "master") ~@body
(s/includes? ~b "release") ~@body
:else false))
Note the backtick around the macro body and the ~
in front of b
each time to expand its value.
A caution here is that will evaluate b
each time it is mentioned -- because the expression is substituted into each place. It's usually safer in macros to introduce a local bound name for the argument to ensure it is only evaluated once:
(defmacro branch?
"Validate if the branch is actionable"
[b & body]
`(let [b# ~b]
(cond (= b# "develop") ~@body
(= b# "master") ~@body
(s/includes? b# "release") ~@body
:else false)))
@overde Like this...~@body
isn't appropriate there
perhaps (do ~@body)
I'd probably write it with a when
and an or
so there's only one copy of ~@body
(defmacro branch?
"Validate if the branch is actionable"
[b & body]
`(let [b# ~b]
(when (or (= b# "develop")
(= b# "master")
(s/includes? b# "release"))
~@body)))
the difference is the behavior if the index is not found
+user=> (nth [] 1)
IndexOutOfBoundsException clojure.lang.PersistentVector.arrayFor (PersistentVector.java:158)
+user=> (get [] 1)
nil
+user=> (nth [] 1 :not-found)
:not-found
+user=> (get [] 1 :not-found)
:not-found
why not contains?
for that?