This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-08-16
Channels
- # admin-announcements (2)
- # bangalore-clj (3)
- # beginners (15)
- # boot (303)
- # carry (18)
- # cider (7)
- # cljs-dev (222)
- # cljsrn (103)
- # clojure (196)
- # clojure-czech (2)
- # clojure-russia (69)
- # clojure-spec (21)
- # clojure-uk (48)
- # clojurescript (68)
- # cursive (18)
- # datomic (185)
- # events (1)
- # hoplon (2)
- # lambdaisland (1)
- # leiningen (1)
- # mount (10)
- # off-topic (1)
- # om (14)
- # onyx (154)
- # parinfer (1)
- # pedestal (3)
- # planck (5)
- # protorepl (9)
- # re-frame (17)
- # reagent (27)
- # ring (2)
- # specter (58)
- # test-check (1)
- # testing (7)
- # untangled (59)
- # yada (35)
ideally, I’d like to be able to navigate to a value using walker, and then just setval to nothing, not nil, but nothing, is that possible?
@conaw: Perhaps navigate one step behind using selected?
and then transform with dissoc. Still not elegant though
so, heres where I’m stuck. right now I’m able to filter out a given value from a vector that is nested one level deep, I’m trying to figure out how to do this recursively though so I could go as deep as needed. the following works
(defpathedfn remove-x [x]
(filterer #(not= x %)))
(defn t3 [v a]
(select [
(remove-x a)
ALL
(if-path vector?
(remove-x a)
STAY)] v))
(deftest test1
(testing "removal"
(is
(= [1 2 3 [4]]
(t3 [1 2 3 [4 5] 5] 5)))))
what I want is
(= [1 2 3 [4 [6]]]
(t3 [1 2 3 [4 [5 6] 5] 5] 5))@conaw: here's one way to do it
(defn remove-x [x]
(fn [v]
(filterv #(not= x %) v)))
(declarepath AllVectors)
(providepath AllVectors
(if-path vector?
(stay-then-continue
ALL
AllVectors)))
(transform AllVectors (remove-x 5) [1 2 3 [4 [5 6] 5] 5])
you could also use ALL-ELEM-SEQ
from that linked github issue in conjunction with AllVectors
which would look like: (setval [AllVectors ALL-ELEM-SEQ #(= 5 (first %))] nil [1 2 3 [4 [5 6] 5] 5])
I'm attempting to "shake" a map of all top level keys where where a deeply nested key in each branch matches a predicate. Is that something I would tackle with transform? Or would I use select in combination with filterer?
what's an example of the input/output you're looking for?
In this map, I only want to keep top level branches where at least one of the maps in :where have an :op value of "="
{:k1 {:where [{:op "="
:value "A"}
{:op "ignore"
:value "X"}]}
:k2 {:where [{:op "<"
:value "A"}
{:op "lookup"
:value "C"}]}
:k3 {:where [{:op "="
:value "A"}
{:op "lookup"
:value "E"}]}}
; result
{:k1 {:where [{:op "="
:value "A"}
{:op "ignore"
:value "X"}]}
:k3 {:where [{:op "="
:value "A"}
{:op "lookup"
:value "E"}]}}
I can build a path to :op no problem, but I lose all parent values when using select
. I considered using collect-one
at the root of the path while applying filterer
at the :op level, but I got the impression I was misunderstanding something fundamental. 🙂
(into {} (traverse [ALL (selected? LAST :where ALL :op #(= "=" %))] data))
you can do it with select
too but traverse
is more efficient
(doesn't create any intermediate sequence)
In your code response, what's the difference between 1) using filterer
, or 2) passing an anonymous function to the selection path, as you did?
filterer navigates you to a new sequence
a function acts as a predicate and stops navigation at that point if the predicate is false
for selected?
, it acts as a predicate where "true" is when anything is selected
since filterer doesn't stop navigation, that wouldn't be relevant in this case
no problem
this is worth reading through if you haven't already: https://github.com/nathanmarz/specter/wiki/List-of-Navigators
any hints how to rewrite this code to be specter 0.12 compatible? https://github.com/binaryage/dirac/blob/417b81c3959e9b156f148f9448f2935f33631658/src/implant/dirac/implant/automation/reps.cljs#L43-L52
I’m getting "Cannot read property '0' of null” somewhere deep in specter and I wasn’t able to figure out what is going wrong 😞
the RepWalker is used in this function: https://github.com/binaryage/dirac/blob/417b81c3959e9b156f148f9448f2935f33631658/src/implant/dirac/implant/automation/reps.cljs#L62-L63
@darwin: need a reproducible test case
Is it okay to nest selected?
functions? Going back to your (into {} (traverse [ALL (selected? LAST :where ALL :op #(= "=" %))] data))
response, what if I wanted to also restrict the selection to the :where vec having a count greater than one?
Okay, I think I got it? Two separate selected?
expressions:
(traverse [s/ALL
(s/selected? s/LAST :where #(< 1 (count %)))
(s/selected? s/LAST :where s/ALL :op #(= "=" %))] data)
@joshkh: I think you could do it with (traverse [ALL (selected? LAST :where #(< 1 (count %)) ALL :op #(= "=" %))] data)
also, if you're traversing a map, you could use MAP-VALS
instead of LAST
Ah, that's what how I was thinking about it originally, but I wasn't sure how ALL fit into the path after the function. I guess the obvious answer is that it fits in just fine. 🙂
And thanks for the advice about MAP-VALS. It'll be easier to remember the data structure when I come back to this in the future.
for sure, and it should be a little more efficient, too!
ALL
is needed in this case since traverse must emit key/value pairs
good point @nathanmarz. I'm not thinking very clearly today. @joshkh, you can't use MAP-VALS
, since MAP-VALS
acts the same as [ALL LAST]
, but you need the ALL
outside of selected?
and LAST
inside it.
@nathanmarz: much obliged
I was having working at a big reduce today and I thought, maybe specter will be able to help me. Basically the atomic input is:
[{:timestamp 14424
:chat-id 2
:payload "bla"}
{:timestamp 14421
:chat-id 1
:payload "asd"}
{:timestamp 14400
:chat-id 1
:payload "test"}]
I have a list of those that I want to convert to a map indexed by chat-id
but keeping the oldest timestamp in the value, as:
{1 {:timestamp 14000 :messages [the list]}
2 {:timestamp 14424 :messages [the list]}}
Can you folks give me a hint (without full solution is fine) from where to start exploring a solution with specter?@richiardiandrea: could you give a small example of input/output?
@codonnell: thanks for answering, yes of course, is the above not enough? I am worried it can take too much space
@richiardiandrea: Thanks, that clarifies it.
Would you list just be a list of the payloads for all messages with the given chat-id?
so I need to carry with me the :timestamp
the calculation on the timestamp is a bit mysterious to me at the moment
Does the list of messages need to be in order of timestamp?
(specter newbie)
yes preferably yes