Fork me on GitHub
#clojure-nl
<
2022-03-31
>
Thierry12:03:43

https://app.slack.com/team/U02CX2V8PJN [2:47 PM] Quick question? I am trying to convert a map with nested maps into a vector with nested vectors while retaining the key as vector entry and value as vector entry. Taking this map: {:keya 1 :keyb {:abc 12 :xyz 34} :keyc 3} I want it to look like this:`[:keya 1] [:keyb [:abc 12] [:xyz 34]] [:keyc 3]` This works but fails when there are nested maps in the map: (let [mykeys (into [] (for [keyword (keys {:keya 1 :keyb 2 :keyc 3})] (symbol keyword)))] (for [key mykeys] [(symbol (format ":x:%s" (str key))) key])) ;;=> ([:x:keya keya] [:x:keyb keyb] [:x:keyc keyc]) with a nested map: (let [mykeys {:keya 1 :keyb {:abc 12 :xyz 34} :keyc 3}] (for [key (keys mykeys)] [(keyword (format "x%s" (str key))) (key mykeys)])) ;; => ([:x:keya 1] [:x:keyb {:abc 12, :xyz 34}] [:x:keyc 3]) I want to avoid adding an unknown amount of for loops to handle the nested maps. Reading up on how to do this brought me to postwalk, but I am not familiar with it. How would I go about getting an output like mentioned above? All I got so far is this: (clojure.walk/postwalk #(if (map? %) (into [] (vals %)) %) {:keya 1 :keyb {:abc 12 :xyz 34} :keyc 3}) ;;=> [1 [12 34] 3]

tvaughan13:03:32

(println
 (clojure.walk/postwalk
  #(if (map? %)
     (mapv vec %)
     %)
  {:keya 1 :keyb {:abc 12 :xyz 34} :keyc 3}))

🙌 1
Thierry13:03:56

man, thanks so much!

👍 1
Thierry15:03:48

So this returns ;; => [[:keya 1] [:keyb [[:abc 12] [:xyz 34]]] [:keyc 3]] How would I go about removing the surrounding vector and making it a lazy-seq?

Thierry15:03:55

nvm, just found it.

Thierry15:03:59

lazy-seq instead of mapv