6

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

2
  • I'm curious what the use-case for this is. Pray tell. Commented Mar 23, 2014 at 11:40
  • I did a priority search tree implementation with maps and I wanted to visualize this nested map tree structure using the vijual library (which print nice ascii tree representations) But vijuals only accept nested vectors. Commented Mar 23, 2014 at 12:26

2 Answers 2

7

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] 
Sign up to request clarification or add additional context in comments.

Comments

5

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.