specter

Latest version: 1.1.3
jeaye 2020-09-29T02:03:45.003200Z

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 Wang 2020-09-29T02:16:02.003600Z

using walker?

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

jeaye 2020-09-29T02:31:01.003800Z

I'll benchmark it.

jeaye 2020-09-29T02:34:28.005400Z

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.

jeaye 2020-09-29T02:37:36.005900Z

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

Lucy Wang 2020-09-29T06:50:53.006400Z

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}})