This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-09-20
Channels
- # beginners (43)
- # boot (44)
- # chestnut (17)
- # cider (78)
- # cljs-dev (24)
- # cljsrn (16)
- # clojure (84)
- # clojure-dusseldorf (1)
- # clojure-italy (21)
- # clojure-losangeles (2)
- # clojure-russia (140)
- # clojure-sg (2)
- # clojure-spec (8)
- # clojure-uk (16)
- # clojurescript (23)
- # cursive (7)
- # datascript (1)
- # datomic (18)
- # docker (20)
- # ethereum (1)
- # fulcro (16)
- # garden (4)
- # graphql (27)
- # hoplon (9)
- # jobs (4)
- # luminus (34)
- # off-topic (6)
- # om (4)
- # onyx (35)
- # pedestal (3)
- # re-frame (24)
- # ring-swagger (15)
- # rum (6)
- # shadow-cljs (22)
- # spacemacs (8)
- # specter (22)
- # yada (7)
@nathanmarz Thanks for the example!
The overview is helpful too... I've not really used zippers before
For the part you don't think I should include - are you saying the example zipper?
"Let's also define a sample zipper that we can work with in the examples below.
(def data [1 [[2 3 4] 5 6] 7 [8 9]])
(def data-zipper (zip/vector-zip data))
"I added the example of NODE-SEQ that you gave me, as well as a few others to compare to selecting and also using NODE instead
@michaelwfogleman yea, I wouldn't include data-zipper
that should all be encapsulated in the paths
OK, I think I've got what you are saying! 🙂
Cool, just pushed a new version - let me know if that's not what you had in mind, or you see anything else 🙂
I still see zipper data structures printed out as results to the examples
like for (S/select-any [SZ/VECTOR-ZIP SZ/DOWN] data)
Got it, I see what you're saying now, that does make it a lot neater. I pushed a new version and also added your comment about the three steps - I can remove that but I found what you said useful 🙂
I’m wrestling with figuring out recursive paths. Specifically, I’m processing and transforming some JSON-LD. I’d like to perform some transformations at any level of the tree, with arbitrary nesting. To simplify, consider a map where keys are primitive strings and values can be a primitive, a nested map, or a vector of nested maps.
A standard transformation might be: if a map has a key jkl:mno
equal to wibble
, add a new key jkl:123
equal to whammy
. Here’s a test map:
{"abc:def": [{"abc:ghi": {"jkl:mno": "womble",
"jkl:qrs": 12345}},
{"abc:tuv": {"jkl:mno": "wibble",
"abc:def": {"abc:ghi": [{"jkl:mno": "wibble",
"jkl:qrs": 0 },
{"jkl:qrs": 20}]}}}],
"abc:wxy": {"abc:def": {"jkl:mno": "wibble"}}}
walker
terminates as soon as it matches, so it’s clear a recursive path is needed. Is recursive-path
the right one to be using, or is this a job for a extend-protocolpath
providing implementations for vectors and maps?
Some of the maps are sorted-maps
, as well, to influence the serialization when the JSON is written out, so just providing an implementation for clojure.lang.PersistentHashMap
won’t cut it in the latter case.
@pataprogramming use recursive-path
I'll show you how
one sec
(def data
{"abc:def" [{"abc:ghi" {"jkl:mno" "womble",
"jkl:qrs" 12345}},
{"abc:tuv" {"jkl:mno" "wibble",
"abc:def" {"abc:ghi" [{"jkl:mno" "wibble",
"jkl:qrs" 0 },
{"jkl:qrs" 20}]}}}],
"abc:wxy" {"abc:def" {"jkl:mno" "wibble"}}})
(def MY-WALKER
(recursive-path [] p
(continue-then-stay
(cond-path
map? [MAP-VALS p]
sequential? [ALL p]
))))
(setval [MY-WALKER map? (selected? (keypath "jkl:mno") (pred= "wibble")) (keypath "jkl:123")] "whammy" data)
@nathanmarz: Oh, great, thanks! cond-path
is what I didn’t know I was groping for. And that example also helps make it clear how to use self-sym
, which I wasn’t quite grokking.
Major kudos for specter, by the way. It’s a brilliant library.
happy to hear you're getting good use out of it