This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-04-20
Channels
- # aws (1)
- # beginners (14)
- # boot (30)
- # cider (6)
- # clara (9)
- # cljsjs (3)
- # cljsrn (22)
- # clojure (247)
- # clojure-dusseldorf (75)
- # clojure-france (38)
- # clojure-italy (6)
- # clojure-japan (8)
- # clojure-nl (3)
- # clojure-russia (16)
- # clojure-serbia (4)
- # clojure-spec (1)
- # clojure-uk (53)
- # clojurescript (168)
- # consulting (3)
- # copenhagen-clojurians (1)
- # core-async (7)
- # css (1)
- # datascript (3)
- # datomic (8)
- # dirac (22)
- # events (1)
- # hoplon (2)
- # jobs (1)
- # jobs-discuss (2)
- # leiningen (4)
- # lumo (138)
- # mount (13)
- # nyc (1)
- # off-topic (24)
- # om (34)
- # onyx (15)
- # pedestal (30)
- # re-frame (9)
- # reagent (23)
- # ring (1)
- # ring-swagger (24)
- # rum (6)
- # spacemacs (6)
- # specter (51)
- # uncomplicate (14)
- # unrepl (1)
- # untangled (17)
- # yada (12)
@lvh I don't think specter will be very useful for that
@nathanmarz is there a recursive-path that will not recurse into the transformed value? i.e. (recursive-path [] p [(walker vector?) (stay-then-continue ALL p)])
will go for a while, but I'm still finding something will stackoverflow... core.async, futures, apache client. I'm thinking I need to just run transforms again and again, until it no longer transforms rather than in one big recursive blitz
@albaker that path is defined so it will continue recursing
recursive-path
itself doesn't do anything besides provide you the programmer the ability to have the path refer to itself
if it's stack overflowing, then you're doing something wrong in your program
I'm okay recursing, just not into the results, so I recurse down to the last known genration, apply and end
I don't know what that means
whatever logic you want will need to be encoded in the path
you can use value collection to keep track of how many levels you've recursed
and then check that using collected?
to have the path decide whether or not to recurse
or you can encode in your data itself information to allow the path to decide whether to recurse
e.g. using metadata
yea, that would work too
lots of options available to control termination
you mean with an exception or something?
I guess you could make a navigator which does that
try catch over invoking next-fn, and when your special exception is thrown it returns the structure unchanged
imo that's a dirty way to solve this and you're better off more precisely specifying when you want recursion to stop
it's using exceptions for flow control
ah sweet, found the bug, took the exception out, and now have a near general purpose specter+stardog graph walker for recursively expanding graph data
@nathanmarz thanks for all the help - this is really nice, with like 6 lines of specter, and a few lines of SPARQL, this thing walks and queries and walks again. I'll give a shot out in the blog that'll fall out from this
@albaker no problem, happy to help
I have a (maybe similar?) question. Happy to post on StackOverflow if I can formulate it correctly. I think the imaginary code I want may explain best:
(def TreeValues
(s/recursive-path [] p
(s/if-path #(not (empty? (:children %)))
(s/submap [:id :name {{ set :children to [:children s/ALL p] }} ])
(s/submap [:id :name :children]))))
is this possible without an inner transform
? Maybe with some use of collect
that I haven’t hit on yet?
essentially it’s operating on a vector of maps, where each map has a :children
key with a vec of the same type of map
I’m just trying to prune each level to the keys I want
submap isn't going to prune keys
it lets you operate on a portion of the map with the result being merged back into the original map
I think you want to use continue-then-stay
hmm, OK thanks. I got the notion of pruning because this is the closet I got, but it only returns the leaves
(recursive-path [] p (continue-then-stay :children ALL p))
(def TreeValues
(s/recursive-path [] p
(s/if-path #(not (empty? (:children %)))
[:children s/ALL p]
(s/submap [:id :name :children]))))
then you could do: (transform TreeNodes #(select-keys % [:id :name :children]) data)
ok, thanks - reading up on continue-then-stay
and trying it out
that works, thanks!
I’m lacking some intuition though . . . I don’t understand why this works:
(transform [ALL TreeNodes] #(select-keys % [:id :name :children]) data)
but not this:
(transform [FIRST TreeNodes] #(select-keys % [:id :name :children]) data)
what's not working?
the latter does something, I’m not sure what, on the whole data vec. I thought it would be equivalent to:
(transform [ALL TreeNodes] #(select-keys % [:id :name :children]) (take 1 data))
no, it will just do the transformation on the first element of the vector
you'll still get the whole vector back, but everything beyond the first element will be untouched
oh, got it
transform always operates on a select portion of the data structure, with the path specifying how to navigate to what needs to be operated on
makes sense, I think I understood that but just dropped the context of the basics when struggling with this problem. Thanks