I was wondering what the most idiomatic way would be in clojure to transform a nested map to a nested vector.
For example from:
{:left {:left {:left 1, :right 5, :middle 1, :score 10}, :right {:left 7, :right 8, :middle 7, :score 0}, :middle 5, :score 10}, :right 9, :middle 8, :score 10}
to:
[ [ [ 1, 5, 1, 10 ], [ 7, 8, 7, 0], 5, 10], 9, 8, 10]
Many thanks
You can use clojure.walk/postwalk
to traverse Clojure data structures in post-order (i.e. start at the leaves) and replace the maps with a vector of [:left :right :middle :score]
values:
(require '[clojure.walk :refer [postwalk]])
(def nested-map
{:left {:left {:left 1, :right 5, :middle 1, :score 10},
:right {:left 7, :right 8, :middle 7, :score 0},
:middle 5,
:score 10},
:right 9,
:middle 8,
:score 10})
(postwalk
(fn [v]
(if (map? v)
((juxt :left :right :middle :score) v)
v))
nested-map)
;; => [[[1 5 1 10] [7 8 7 0] 5 10] 9 8 10]
My shot at it:
(clojure.walk/postwalk #(if (map? %) (into [] (vals %)) %) nested-map)
=> [[5 10 [7 0 8 7] [1 10 5 1]] 8 9 10]
It doesn't preserve order when used with hash-maps; it will however, preserve order with array-maps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With