Fork me on GitHub
#specter
<
2018-01-17
>
jeremys16:01:22

Hey guys I have been scratching my head for some time now. I want to operate the following transformation :

["toto"
{:tag tag-to-unwrap :content ["titi" "tutu"]}
{:tag tag-to-unwrap :content ["toto"]}]
;=>
["toto" "titi" "tutu" "toto"]
Right now with:
(transform [ALL XML-ZIP NEXT-WALK NODE map? #(= :tag-to-unwrap (:tag %))]
:content
["toto"
{:tag tag-to-unwrap :content ["titi" "tutu"]}
{:tag tag-to-unwrap :content ["toto"]}])
I get
["toto" ["titi" "tutu"] ["toto"]]
Can I get specter to “splice” the vectors ["titi" "tutu"]and ["toto"]in the result?

nathanmarz16:01:04

@jeremys with what's built-in you can do something like this:

(require '[com.rpl.specter.zipper :as z])

(def data
  ["toto"
    {:tag :a :content ["titi" "tutu"]}
    {:tag :a :content ["toto"]}]
  )

(transform
  [z/VECTOR-ZIP
   z/DOWN
   z/NEXT-WALK
   (selected? z/NODE map?)
   z/NODE-SEQ]
  #(select [FIRST :content ALL] %)
  data)

nathanmarz16:01:10

it's also pretty easy to make an ALL-SEQ navigator which navigates to each element as a 1 element sequence, and then you could do:

(transform [ALL-SEQ (selected? FIRST map?)]
  #(select [FIRST :content ALL] %)
  data
  )

nathanmarz16:01:45

technically this would work: (def ALL-SEQ (path z/VECTOR-ZIP z/DOWN z/NEXT-WALK z/NODE-SEQ))

nathanmarz16:01:54

though you could make it more efficient with a custom navigator

nathanmarz16:01:46

another solution:

(transform (continuous-subseqs map?)
  #(select [ALL :content ALL] %)
  data
  )

jeremys16:01:47

Thx @nathanmarz I’ll take a look and see what I can come up with.