Skip to content

Instantly share code, notes, and snippets.

@razum2um
Last active June 14, 2017 17:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save razum2um/b691ad0d760795efaeb886e6caf05122 to your computer and use it in GitHub Desktop.
Save razum2um/b691ad0d760795efaeb886e6caf05122 to your computer and use it in GitHub Desktop.
(defn postwalk-with-side-effect [x]
(let [state (atom [])
side-effect (fn [x] (if (:data x) (swap! state conj (:data x))))]
(clojure.walk/postwalk (fn [x] (side-effect x) x) x)
@state))
(defn test []
(= [1 2 3]
(postwalk-with-side-effect
{:data 3 :children [{:children {:children []}}
{:children [{:children [] :data 1}]}
{:children [] :data 2}]})
))
@noisesmith
Copy link

noisesmith commented Jun 14, 2017

this avoids mutating, doesn't have to build a collection that nobody uses, and for those reasons is likely more performant

(defn tree-seq-and-reduce
  [x]
  (reduce (fn [state el]
            (if-let [datum (:data el)]
              (conj state datum)
              state))
          []
          (tree-seq coll? seq x)))

(defn test-it
  []
  (= (set [1 2 3])
     (set (tree-seq-and-reduce
           {:data 3 :children [{:children {:children []}}
                               {:children [{:children [] :data 1}]}
                               {:children [] :data 2}]}))))

(test-it)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment