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 [email protected]
>>> > Note that posts from new members are moderated - please be patient
>>> > with your first post.
>>> > To unsubscribe from this group, send email to
>>> > [email protected]
>>> > 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 [email protected].
>>> > 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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/groups/opt_out.