This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-08-19
Channels
- # admin-announcements (2)
- # beginners (25)
- # boot (93)
- # cider (2)
- # clara (2)
- # cljs-dev (63)
- # cljsjs (3)
- # cljsrn (38)
- # clojure (142)
- # clojure-austin (1)
- # clojure-brasil (2)
- # clojure-czech (1)
- # clojure-dev (7)
- # clojure-greece (1)
- # clojure-russia (170)
- # clojure-spec (11)
- # clojure-uk (65)
- # clojurescript (46)
- # clojurex (1)
- # code-reviews (3)
- # cursive (11)
- # datomic (35)
- # euroclojure (6)
- # events (2)
- # flambo (2)
- # hoplon (115)
- # instaparse (11)
- # jobs (21)
- # jobs-rus (3)
- # lambdaisland (2)
- # off-topic (17)
- # om (35)
- # onyx (161)
- # planck (1)
- # protorepl (7)
- # random (1)
- # re-frame (31)
- # reagent (19)
- # ring-swagger (21)
- # rum (5)
- # spacemacs (3)
- # specter (25)
- # test-check (20)
- # testing (7)
- # untangled (2)
- # yada (50)
I have another newbie question regarding Specter. Is this something that I can easily do? I have nested vectors of strings representing a tree. If a vector directly follows a string then it is a subtree. I'd like to update the tree in a similar fashion to update-in when dealing with maps. In this non working example I'd want to append "SUB-A-2-2-2" to the "SUB-A-2-2" "node.":
(let [t ["A"
["SUB-A-1"
"SUB-A-2"
["SUB-A-2-1"
"SUB-A-2-2"
["SUB-A-2-2-1"]]]]]
(s/transform ["A" "SUB-A-2" "SUB-A-2-2"]
(fn [node] (conj node "SUB-A-2-2-2"))
t)
#_["A"
["SUB-A-1"
"SUB-A-2"
["SUB-A-2-1"
"SUB-A-2-2"
["SUB-A-2-2-1"
; New:
"SUB-A-2-2-2"]]]])
I can't quite figure out how to work something like #(.indexOf nested-vec %)
into the selection path, presumably recursively. Which makes me think I need a walker?
@rodeorockstar: cleanest way is to define a new navigator that determines which index to navigate to dynamically
(defnav dynamic-nth [afn]
(select* [this structure next-fn]
(next-fn (nth structure (afn structure))))
(transform* [this structure next-fn]
(let [i (afn structure)]
(assoc structure i (next-fn (nth structure i))))))
(defnavconstructor subtree
[p dynamic-nth]
[v]
(p (fn [avec] (inc (.indexOf avec v)))))
example:
(transform
[(subtree "A")
(subtree "SUB-A-2")
(subtree "SUB-A-2-2")
ALL]
#(str % "!")
data)
;; => ["A" ["SUB-A-1" "SUB-A-2" ["SUB-A-2-1" "SUB-A-2-2" ["SUB-A-2-2-1!"]]]]
@rodeorockstar: that said, I would recommend storing your tree in a different format, as right now you're basically required to parse it as you traverse it
your particular example can be done like this:
(setval [(subtree "A") (subtree "SUB-A-2") (subtree "SUB-A-2-2") END]
["SUB-A-2-2-2"]
data)
That is so cool... Thanks for the example, @nathanmarz . I'll comb over the devnav
devnavconstructor
macros until they settle in my head. Agreed, the tree structure isn't ideal, and I changed it since asking the question. But I was still curious if something like that could be done with specter so it remained a useful exercise to me. I hadn't thought to use defnav
.
yea, the real power of specter is in being able to define your own navigators and then benefit from the combinatorial ways in which everything can be combined
no problem, happy to help
Hi guys, reading codewalker documentation i found “When afn returns a truthy value, codewalker stops searching that branch of the tree and continues its search of the rest of the data structure” So how can i dont stop when afn return true? I just wanna collect when its true and searching that branch of the tree for more patterns to collect. Sorry if the questions isn't clear.
@lellis you probably want something like this:
(declarepath MyCodewalker)
(providepath MyCodewalker
[(codewalker map?)
(continue-then-stay
MAP-VALS
MyCodewalker)])
wondering if anyone knows offhand the best way to transform a map where I want to select keys of a certain set and map their children into a final map of {:keyname child}
@mattsfrey what's an example of input/output?
ty! @nathanmarz Done!!
Basically will have a map of "info types" that are an array of sub maps, I want to pull out the child sub maps and put them into a flat structure as such
here's how I would do it:
(def data {:phone-numbers [{:type "work" :value "720-1234"}
{:type "home" :value "720-1235"}]
:organizations [{:name "Google" :title "Software Engineer"}]
:bleh "blah..."})
(->> data
(traverse [ALL
(not-selected? FIRST #{:bleh})
(collect-one FIRST)
LAST
ALL])
(reduce (fn [v [type val]] (conj v {:type type :value val}))
[]))
that seems to be explicitly ignoring bleh whereas I'd rather explicitly include elements of a set and ignore everything else
just change that line to (selected? FIRST #{:organizations :phone-numbers :addresses})