I am very new to Clojure and have an interesting problem for you Clojure gurus. I'm working through the book "Programming Collective Intelligence" and trying to code the examples in Clojure (the book has them all in Python). In the first chapter we have a hash map setup of movie critics and the rankings they've given to different movies. It looks like this:

{"Lisa Rose" {"Lady in the Water" 2.5, "Snakes on a Plane" 3.5 },
"Gene Seymour" {"Lady in the Water" 3.0, "Snakes on a Plane" 3.5}}

The problem is this. How to turn that inside out so that I get a hash map that looks like this:

This assumes that all keys of interest in the inner maps are present on the first inner map. If this is incorrect, (-> m first val keys) would have to be replaced with something returning a collection of all keys of interest, e.g. (->> m (map values) (mapcat keys)).

The idea is to build a map of the form {inner-key {outer-key the-value-at-inner-key-in-the-map-at-outer-key}}, then merge them together appropriately.

Return value on the map in the question text is as specified.

Now, the above creates a lot of intermediate structures, which may be a problem performance-wise. If speed is of the essence, you can switch to loop and transients:

So we get map, (it is collection of vectors [key value]), inverse every entry (vector [key value]). Now we have collection of collections of vectors, concat them to one collection. And finally, using reduce we add every vector to map.