Skip to content

Instantly share code, notes, and snippets.

@bsless
Created April 5, 2020 07:21
Show Gist options
  • Save bsless/6d820d84d2d145bf0958d89798710639 to your computer and use it in GitHub Desktop.
Save bsless/6d820d84d2d145bf0958d89798710639 to your computer and use it in GitHub Desktop.
all paths in a nested map
(defn map-or-vec?
[x]
(or (map? x) (vector? x)))
;;; https://www.reddit.com/r/Clojure/comments/7wl7nt/get_a_list_of_all_paths_in_a_nested_map/
(defn paths
([m]
(paths [] [] m))
([ps ks m]
(reduce-kv
(fn [ps k v]
(if (map-or-vec? v)
(paths ps (conj ks k) v)
(conj ps (conj ks k))))
ps
m)))
@bsless
Copy link
Author

bsless commented Jul 15, 2020

Interesting. What was your use-case?

@KingCode
Copy link

As it happened, I was reading David Nolen's tutorial about Enlive - which uses often-complex nested maps to encapsulate scraped HTML. Without really delving into the ways to navigate to the leaf elements through Enlive, I wanted to see at a glance all paths to a leaf node, discover the paths that interest me (the leaf nodes are usually eye-grabbing at the REPL from being a path's last element) and filter for them, then retrieve the content - in this case a reddit page. From that a quick function can be made to read reddit articles at the repl. (I eventually realised the same can be done much more easily with Enlive's HTML screen scraping, without the need to provide specific paths, so I probably wouldn't have bothered had I read the rest of the tutorial :)

Still, It dawned upon me that path exploration can be useful, and can be done generically to any collection type by extending a few protocols. I'm sure there's a mature library somewhere doing the same, but it was fun to write.

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