This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-06-11
Channels
- # admin-announcements (9)
- # arachne (1)
- # boot (125)
- # cider (5)
- # clara (34)
- # cljs-dev (11)
- # cljsjs (19)
- # clojure (164)
- # clojure-greece (7)
- # clojure-nl (2)
- # clojure-russia (5)
- # clojure-spec (3)
- # clojurescript (28)
- # clojurex (4)
- # core-async (3)
- # cursive (2)
- # datomic (3)
- # hoplon (268)
- # jobs (4)
- # keechma (2)
- # lambdaisland (1)
- # lein-figwheel (5)
- # leiningen (5)
- # off-topic (3)
- # om (3)
- # onyx (16)
- # re-frame (5)
- # reagent (31)
- # robots (1)
- # spacemacs (3)
- # specter (89)
- # untangled (1)
- # yada (26)
I already forgot how to do this: https://gist.github.com/luxbock/3403337442fb3782321209edaa7fffc0
@luxbock: not sure if this is optimal, but it works
(transform [MAP-VALS (collect-one (filterer (fn [m] (contains? m :foo))))] (fn [ms _] (count ms)) data)
@luxbock: I would do it like this:
(transform [MAP-VALS (collect ALL (pred :foo))]
(fn [a _] (count a))
{:a [{:foo 1} {:bar 3} {:foo 4}]
:b [{:foo 1} {:bar 3 :foo 4} {:foo 4}]}
)
can also use must
instead of pred
for contains?
semantics
I'm trying to understand how late binding works for filterer. It seems to work fine if I pass it a late binding navigator, like must or pred. However, if I try to pass a predicate function directly, I get an exception. Is that just how filterer works or am I missing something?
@codonnell: filterer
isn't a navigator
it's a function that returns a navigator
so when you use it in comp-path
it gets interpreted like all functions do – as a filter function
filterer
can be invoked with a path that requires more parameters to then create a navigator that requires those parameters
btw, it's very rare that you need to explicitly precompile anymore
(select-one (filterer even?) (range 10))
in 0.11.2 should be within 2-3% of the precompiled code
Alright, that makes sense. Thanks for the response. I'm aware that compiling paths is generally unnecessary in 0.11.2. I'm writing up some notes for myself and got confused about filterer behavior, so I wanted to clarify for my notes.
Specter should detect that mistake and throw an error
I appreciate that. Informative error messages make a huge difference.
Are you using 0.11.1 or later?
you should use the built-in one as its about twice as fast at [ALL LAST]
it was added in 0.11.1
Highly recommend upgrading to 0.11.2
@nathanmarz: regarding @luxbock’s example, when I do
(transform [ALL LAST (sp/collect ALL (sp/pred :foo))]
count
{:a [{:foo 1} {:bar 3} {:foo 4}]
:c [{:foo 1} {:bar 3 :foo 4} {:foo 4}]})
;;=> {:a 2 c: 3}
(transform [MAP-VALS (sp/collect ALL (sp/pred :foo))]
(fn [e _] (count e))
{:a [{:foo 1} {:bar 3} {:foo 4}]
:c [{:foo 1} {:bar 3 :foo 4} {:foo 4}]})
;;=> 0
(transform [MAP-VALS (sp/collect ALL (sp/pred :foo))]
count
{:a [{:foo 1} {:bar 3} {:foo 4}]
:b [{:foo 1} {:bar 3 :foo 4} {:foo 4}]})
;;=> 0
(transform [MAP-VALS (collect ALL (must :foo))] (fn [c _] (count c)) data)
{:a 2, :b 3}
ah, interesting
(transform [ALL LAST (sp/collect ALL (sp/must :foo))]
count
{:a [{:foo 1} {:bar 3} {:foo 4}]
:b [{:foo 1} {:bar 3 :foo 4} {:foo 4}]})
;;=> {:a 2 :b 3}
@conaw: not reproducing your [ALL LAST] vs. MAP-VALS
I'm not sure how those are working with plain count. Shouldn't the transforming function get passed two values?
I get an exception that count is passed two values.
it shouldn't be working but it looks like clojurescript doesn't throw an arity exception
it just ignores args beyond the first
this is the exact code I’m running
(transform [ALL LAST (collect ALL (must :foo))]
count
{:a [{:foo 1} {:bar 3} {:foo 4}]
:b [{:foo 1} {:bar 3 :foo 4} {:foo 4}]})
(transform [MAP-VALS (sp/collect ALL (pred :foo))]
(fn [a _] (count a))
{:a [{:foo 1} {:bar 3} {:foo 4}]
:b [{:foo 1} {:bar 3 :foo 4} {:foo 4}]})
(transform [ALL LAST (collect ALL (must :foo))]
(fn [a _] (count a))
{:a [{:foo 1} {:bar 3} {:foo 4}]
:b [{:foo 1} {:bar 3 :foo 4} {:foo 4}]})
cljs.user=>
(transform [s/MAP-VALS (s/collect s/ALL (s/pred :foo))]
(fn [a _] (count a))
{:a [{:foo 1} {:bar 3} {:foo 4}]
:b [{:foo 1} {:bar 3 :foo 4} {:foo 4}]})
{:a 2, :b 3}
cljs.user=>
(transform [s/MAP-VALS (s/collect s/ALL (s/must :foo))]
(fn [a _] (count a))
{:a [{:foo 1} {:bar 3} {:foo 4}]
:b [{:foo 1} {:bar 3 :foo 4} {:foo 4}]})
{:a 2, :b 3}
are you redefining MAP-VALS?
are you doing it from a fresh repl?
(require '[com.rpl.specter :as s])
(require-macros '[com.rpl.specter.macros :refer [select transform]])
(transform [s/MAP-VALS (s/collect s/ALL (s/pred :foo))]
(fn [a _] (count a))
{:a [{:foo 1} {:bar 3} {:foo 4}]
:b [{:foo 1} {:bar 3 :foo 4} {:foo 4}]})
and that exact code returns 0?
doesn't make any sense
you'll need to put up a repo and instructions to reproduce it
oh one more idea
what version of cljs?
what version of clojure are you pairing that with?
1.9.0-alpha4?
i just tried on those exact versions and it works fine
so yea, need a repo to see what's going on
thanks @nathanmarz
@nathanmarz: must be something on my end, created a new clean project and got it working fine
Does anyone know how subselect is meant to be used?
I’ve just published a library that has specter paths for working with formatted EDN and clojure code: https://github.com/maitria/specter-edn
@codonnell: subselect
navigates you to the elements in the given path and lets you manipulate them as a sequence, but transformations will be applied back at the original locations
(transform (subselect (walker number?) even?)
reverse
[1 [[[2]] 3] 5 [6 [7 8]] 10])
;; => [1 [[[10]] 3] 5 [8 [7 6]] 2]
@eraserhd: very cool!