Okay, so this is a very old question with lots of good answers, but I built a versatile, versatile, Swiss army knife, Map inverter, and this is the place to publish it.
These are actually two inverters. One for individual cost items ...
//from Map[K,V] to Map[V,Set[K]], traverse the input only once implicit class MapInverterA[K,V](m :Map[K,V]) { def invert :Map[V,Set[K]] = m.foldLeft(Map.empty[V, Set[K]]) { case (acc,(k, v)) => acc + (v -> (acc.getOrElse(v,Set()) + k)) } }
... and another, very similar, for collections of meanings.
import scala.collection.generic.CanBuildFrom import scala.collection.mutable.Builder import scala.language.higherKinds //from Map[K,C[V]] to Map[V,C[K]], traverse the input only once implicit class MapInverterB[K,V,C[_]](m :Map[K,C[V]] )(implicit ev :C[V] => TraversableOnce[V]) { def invert(implicit bf :CanBuildFrom[Nothing,K,C[K]]) :Map[V,C[K]] = m.foldLeft(Map.empty[V, Builder[K,C[K]]]) { case (acc, (k, vs)) => vs.foldLeft(acc) { case (a, v) => a + (v -> (a.getOrElse(v,bf()) += k)) } }.mapValues(_.result()) }
using:
Map(2 -> Array('g','h'), 5 -> Array('g','y')).invert //res0: Map(g -> Array(2, 5), h -> Array(2), y -> Array(5)) Map('q' -> 1.1F, 'b' -> 2.1F, 'c' -> 1.1F, 'g' -> 3F).invert //res1: Map(1.1 -> Set(q, c), 2.1 -> Set(b), 3.0 -> Set(g)) Map(9 -> "this", 8 -> "that", 3 -> "thus", 2 -> "thus").invert //res2: Map(this -> Set(9), that -> Set(8), thus -> Set(3, 2)) Map(1L -> Iterator(3,2), 5L -> Iterator(7,8,3)).invert //res3: Map(3 -> Iterator(1, 5), 2 -> Iterator(1), 7 -> Iterator(5), 8 -> Iterator(5)) Map.empty[Unit,Boolean].invert //res4: Map[Boolean,Set[Unit]] = Map()
I would prefer both methods to be in the same implicit class, but the more time I spent studying it, the more problematic it turned out to be.