Могу предложить следующее: У нас есть карта - коллекция записей.Переверните каждую запись наизнанку, и они объединят их: По умолчанию:
{:Lisa {:Lady 2.5, :Snakes 3.5},
:Gene {:Lady 3.0, :Snakes 3.5}}
Инвертируйте каждую запись:
([:Lady {:Lisa 2.5}], [:Snakes {:Lisa 3.5}])
([:Lady {:Gene 3.0}], [:Snakes {:Gene 3.5}])
Конкатируйте их:
([:Lady {:Lisa 2.5}], [:Snakes {:Lisa 3.5}], [:Lady {:Gene 3.0}], [:Snakes {:Gene 3.5}])
И они объединят ихна одну карту:
{:Lady {:Lisa 2.5, :Gene 3.0},
:Snakes {:Lisa 3.5, :Gene 3.5}}
Код:
(defn inverse-map [m]
(let [inverse-entry (fn [[name movies]]
(map (fn [[movie rating]]
[movie {name rating}])
movies))]
(->> (map inverse-entry m)
(reduce concat)
(reduce (fn [res [movie entry]]
(update-in res [movie] merge entry))
{}))))
Таким образом, мы получаем карту (это набор векторов [значение ключа]), инвертирующий каждую запись (вектор [значение ключа]).Теперь у нас есть коллекция коллекций векторов, объединяющих их в одну коллекцию.И, наконец, используя Reduce, мы добавляем каждый вектор на карту.
Полагаю, есть более элегантное решение, но мое тоже работает.