Fork me on GitHub
#specter
<
2017-06-02
>
wilkerlucio13:06:13

hello, I would like to use specter to apply a function to all map keys (recursively) on a map, can someone please give me an example on doing that?

nathanmarz13:06:38

@wilkerlucio can you show a specific example of a transformation?

nathanmarz13:06:47

that should be pretty easy

wilkerlucio13:06:04

@nathanmarz sure, something like this:

{:person/name "Bla"
 :person/child {:child/something "other"
                :child/bla {:subchild/entry "blabla"}}}
to this:
{:name "Bla"
 :child {:something "other"
                :bla {:entry "blabla"}}}

wilkerlucio13:06:17

considering it can have N nesting fields

nathanmarz14:06:27

@wilkerlucio looks like this:

(def data
  {:person/name "Bla"
   :person/child {:child/something "other"
                  :child/bla {:subchild/entry "blabla"}}})

(def MapWalker
  (recursive-path [] p
    (if-path map?
      (continue-then-stay MAP-VALS p))
    ))

(setval [MapWalker MAP-KEYS NAMESPACE] nil data)

souenzzo16:06:04

(def ALL-MAPS
  "All maps of an entity"
  (recursive-path [] p
                  [(walker map?) (stay-then-continue MAP-VALS p)]))

@wilkerlucio those dont work with {:a [{:b :c}]}...

nathanmarz16:06:36

it's generally better not to use walker

nathanmarz17:06:01

but rather make a path that precisely encodes the structure of the data you're working with

nathanmarz17:06:26

walker is brute force which makes it less performant and often causes surprising bugs (e.g. by descending into things you didn't want, like records)

souenzzo17:06:05

There is some other way to define ALL-MAPS (w/o walker)?

nathanmarz17:06:10

that's the new definition of walker I recently committed

nathanmarz17:06:59

can define your ALL-MAPS similarly by handling the different data structure cases in a cond-path

souenzzo17:06:36

(def ALL-MAPS-2
  (recursive-path
    [] p
    (cond-path map? (continue-then-stay MAP-VALS p)
               coll? [ALL p])))
I will try to swap in my code.