And here is the final piece of working code, which we're using to transform 
results from Korma when we join a has one or belongs to association.

(def ^:private rel-attribute-pattern #"(.*)--(.*)$")

(defn- nested-key [k]
  (some-> (re-matches rel-attribute-pattern (name k))
          second
          keyword))

(defn nest-relations
  "Walks the given hash-map, and moves any keys of the form
  <relation>--<attribute> into a nested hash-map."
  [m]
  (let [grouped (group-by (fn [[k _]] (or (nested-key k) ::top)) m)
        top (::top grouped)
        remove-rel #(str/replace % rel-attribute-pattern "$2")]
    (-> (reduce-kv
          #(assoc % %2 (util/update-keys (into {} %3) remove-rel)) {} 
grouped)
        (dissoc ::top)
        (merge (into {} top)))))

This can obviously be refactored and optimised, but does the job for now.

Thank you very much for your help Mr. foo.bar.

On Thursday, 16 January 2014 14:40:24 UTC, James wrote:
>
> Whoops… that's missing an all important (merge (into {} top)).
>
> On Thursday, 16 January 2014 14:36:45 UTC, James wrote:
>>
>> Thanks for the pointers. I've gotten as far as grouping the keys by the 
>> prefix using `group-by`, and added clunky support for keys that aren't 
>> nested like so:
>>
>> ``` clj
>> (defn- nested-key [k]
>>   (some-> (re-matches #"^(.*)--(.*)$" (name k))
>>           second
>>           keyword))
>>
>> (defn nest-relations
>>   "Walks the given hash-map, and moves any keys of the form
>>   <group>--<key> into a nested hash-map."
>>   [m]
>>   (let [grouped (group-by (fn [[k _]] (or (nested-key k) ::top)) m)
>>         top (::top grouped)]
>>     (-> grouped
>>         (dissoc ::top)
>>         (merge top))))
>> ```
>>
>> I end up with vectors instead of hash-maps, and I'm particularly happy 
>> with the code, but it's getting there.
>>
>> On Thursday, 16 January 2014 13:58:45 UTC, Jim foo.bar wrote:
>>>
>>> You could do something like this: 
>>>
>>>
>>> (def v {:a--id 1 :a--name "A" :b--id 2 :b--name "B"}) 
>>>
>>> (group-by #(-> % first str second str keyword) v) 
>>>
>>> =>{:b [[:b--name "B"] [:b--id 2]], :a [[:a--id 1] [:a--name "A"]]} 
>>>
>>> (reduce-kv #(assoc % %2 (into {} %3)) {} *1) 
>>>
>>> => {:a {:a--id 1, :a--name "A"}, :b {:b--name "B", :b--id 2}} 
>>>
>>> all that's left is the names in the inner map... 
>>>
>>> HTH, 
>>>
>>> Jim 
>>>
>>>
>>> On 16/01/14 13:46, James Conroy-Finn wrote: 
>>> > Hello all, 
>>> > 
>>> > I've found myself stuck trying to move matching keys in a hash into a 
>>> > nested hash. 
>>> > 
>>> > For example,: 
>>> > 
>>> > {:a--id 1 :a--name "A" :b--id 2 :b--name "B"} ;=> {:a {:id 1 :name 
>>> > "A"} :b {:id 2 :name "B"}} 
>>> > 
>>> > I've tried `clojure.walk`, I've tried building the args to `assoc-in`, 
>>> > and using `apply`. I honestly feel like I'm missing something really 
>>> > obvious, like something with group-by. 
>>> > 
>>> > Any tips would be greatly appreciated. I'll keep hammering away. 
>>> > -- 
>>> > -- 
>>> > You received this message because you are subscribed to the Google 
>>> > Groups "Clojure" group. 
>>> > To post to this group, send email to clo...@googlegroups.com 
>>> > Note that posts from new members are moderated - please be patient 
>>> > with your first post. 
>>> > To unsubscribe from this group, send email to 
>>> > clojure+u...@googlegroups.com 
>>> > For more options, visit this group at 
>>> > http://groups.google.com/group/clojure?hl=en 
>>> > --- 
>>> > You received this message because you are subscribed to the Google 
>>> > Groups "Clojure" group. 
>>> > To unsubscribe from this group and stop receiving emails from it, send 
>>> > an email to clojure+u...@googlegroups.com. 
>>> > For more options, visit https://groups.google.com/groups/opt_out.  
>>>
>>

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to