Skip to content

Instantly share code, notes, and snippets.

@micheller
Created April 4, 2017 22:22
Show Gist options
  • Save micheller/3e11550d5548a2ab252510d62d5dfb81 to your computer and use it in GitHub Desktop.
Save micheller/3e11550d5548a2ab252510d62d5dfb81 to your computer and use it in GitHub Desktop.
A get-in like tree traverser which supports multiple paths (on vectors)
(defn unpack [alist]
(loop [accum []
alist alist]
(if (empty? alist)
accum
(let [ff (first alist)
func (if (sequential? ff)
concat
conj)]
(recur (func accum ff)
(rest alist))))))
(defn arseny6 [st path]
(loop [struct st
path path]
(if (empty? path)
struct
(cond
(map? struct) (recur
(get struct (first path))
(rest path))
(sequential? struct) (recur
(-> (map #(get % (first path))
struct)
(#(if (empty? (rest path))
%
(unpack %))))
(rest path))))))
(defn arseny-final [st path]
(->> (arseny6 st path)
(filter (complement nil?))))
(arseny-final {:a [
{:b 2
:c [
{:e [
{:x 2 :y 3 :z 1}
{:z 0}
{:z 2}
{:z {:mid 5}}
]
}
{:e [
{:z 1 :yaaay 42}
{:z -1}
{:z [
{:mid 2}
{:mid ["get", "got", "got"]}
]
}
]
}
]
}
{:b 3}
{:b 4}]}
[:a :c :e :z :mid])
;;
;; (5 2 ["get" "got" "got"])
;;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment