This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-03-04
Channels
- # announcements (123)
- # asami (1)
- # babashka (50)
- # beginners (49)
- # biff (21)
- # calva (48)
- # cider (6)
- # clj-yaml (8)
- # cljsrn (2)
- # clojure (9)
- # clojure-conj (1)
- # clojure-indonesia (1)
- # clojure-losangeles (1)
- # clojure-uk (18)
- # clojurescript (21)
- # data-science (19)
- # datahike (13)
- # events (1)
- # fulcro (1)
- # honeysql (4)
- # hyperfiddle (40)
- # improve-getting-started (3)
- # inf-clojure (1)
- # malli (6)
- # off-topic (45)
- # releases (3)
- # rewrite-clj (14)
- # scittle (1)
- # shadow-cljs (57)
- # tools-deps (1)
- # vim (13)
- # xtdb (14)
Does someone have ready function with good performance to get all leaves from tree (map and vectors where leaf is always a map)?
{:a [{:a 1} {:b 2}]
:b [{:a 1} {:b [{:a 1}]}]}
Should return
[{:a 1} {:b 2} {:a 1} {:a 1}]
Of course the tree is much more complex, but only maps and vectors and all leaves are map.If you're already using Specter in that project, I suspect it will give good performance here. But coming up with the right selector might be a tad tricky.
I'd start with something naive like this
(defn leaf?
[x]
(and (map? x) (not (some coll? (vals x)))))
(defn leaves
[x]
(cond
(leaf? x) [x]
(map? x) (mapcat leaves (vals x))
(vector? x) (mapcat leaves x)))
(leaves {:a [{:a 1} {:b 2}]
:b [{:a 1} {:b [{:a 1}]}]})
;; => ({:a 1} {:b 2} {:a 1} {:a 1})
you could then optimize it a bit further by only checking for map?
and vals
once
(defn leaves
[x]
(cond
(map? x) (or (seq (mapcat leaves (vals x))) [x])
(vector? x) (mapcat leaves x)))
I'd start there and then start getting into specter or other weird stuff only if that was too slow
I'll second using Specter. It's awesome. Otherwise look into tree-seq, I suppose.