Fork me on GitHub
#specter
<
2020-09-29
>
jeaye02:09:45

Is there a more efficient way to do this (while keeping the recursive abilities)?

(def ALL-RECURSIVE (recursive-path [] p
                                   (cond-path
                                     map? (stay-then-continue MAP-VALS p)
                                     coll? (stay-then-continue ALL p))))
(transform [ALL-RECURSIVE MAP-VALS (pred #(and (map? %) (contains? % :foo)))]
           :foo
           {:a {:foo :b}}) ; => {:a :b}

Lucy Wang02:09:02

using walker?

(transform [(walker (clojure.core/every-pred map? :foo))]
           :foo
           {:a {:foo :b}})

jeaye02:09:01

I'll benchmark it.

jeaye02:09:28

A bit slower, it seems. Mine was 11µs. With the walker, it's 13µs. I'm doing some other things in the benchmark, which is why the numbers are higher than just benchmarking that one transform, but those things are constant across both tests.

jeaye02:09:36

Seems like your usage of every-pred is marginally faster than my and, though. 🙂

Lucy Wang06:09:53

Or use meander

(require '[meander.epsilon :as m]
         '[meander.strategy.epsilon :as m*])

(def replace-foo
  (m*/rewrite
   {:foo (m/some ?xs)} ?xs))

(def replace-all-foos
  (m*/until =
    (m*/bottom-up
     (m*/attempt replace-foo))))

(replace-all-foos {:a {:foo :b}})