Search code examples
clojurecompojurehiccupmonger

Clojure convert {"a.b" 1, "a.c" 2, "d.e" 3} to {:a {:b 1, :c 2}, :d {:e 3}} (for compojure/hiccup with monger hierarchy)


My mongodb schema has a JSON hierarchy to it. When I get the field params from compojure, the hash is in flat dotted notation like {"a.b" 1, "a.c" 2, "d.e" 3}. I'm wanting to use monger to insert the data, but that expects a real hierarchical format like {:a {:b 1, :c 2}, :d {:e 3}}. Is there any way to automatically convert from one to the other?


Solution

  • Nothing automatic that I know of, but it's pretty straightforward to do the conversion manually:

    => (require 'clojure.string)
    => (defn nest-keys [x]
         (reduce (fn [m [k v]]
                   (assoc-in m (map keyword (clojure.string/split k #"\.")) v))
                 {}
                 x))
    => (nest-keys {"a.b" 1 "a.c" 2 "d.e" 3})
    {:d {:e 3}, :a {:c 2, :b 1}}