Scala 将映射[A,B]转换为映射[B,设置[A]],然后再转换回来

Scala 将映射[A,B]转换为映射[B,设置[A]],然后再转换回来,scala,Scala,我有一个模拟为地图[位置,玩家]的游戏板。对于 我想把它转换成一些计算 地图[玩家,设置[位置]]。例如,如果我们简化并使用符号 键和值,我要转换: Map('a -> 'X, 'b -> 'O, 'c -> 'X, 'd -> 'O) 为此: Map('O -> Set('b, 'd), 'X -> Set('a, 'c)) (我在写这个问题时提出了一个解决方案,贴在下面。希望大家对此发表意见。也许还有其他更好的方法吗?回答自己,因为我在写这个问题时提出

我有一个模拟为地图[位置,玩家]的游戏板。对于 我想把它转换成一些计算 地图[玩家,设置[位置]]。例如,如果我们简化并使用符号 键和值,我要转换:

Map('a -> 'X, 'b -> 'O, 'c -> 'X, 'd -> 'O)
为此:

Map('O -> Set('b, 'd), 'X -> Set('a, 'c))

(我在写这个问题时提出了一个解决方案,贴在下面。希望大家对此发表意见。也许还有其他更好的方法吗?

回答自己,因为我在写这个问题时提出了一个相当优雅的解决方案:

grid.groupBy(_._2).map(x => x._1 -> x._2.keySet)

我很想知道是否有更好的方法。

分组后,您可以使用
mapValues

m.foldLeft(Map.empty[Symbol, Set[Symbol]].withDefaultValue(Set.empty)) { case (acc, (k, v)) => acc.updated(v, acc(v) + k) }
m.groupBy(_._2).mapValues(_.keySet)

小心使用mapValues(和filterKeys)。他们是懒惰的/返回地图上的视图。我正在处理不可变的地图。这应该意味着我没事,对吧?在这种情况下你很好。请记住,mapValues返回一个“视图”,因此每次使用视图时都会执行mapValues的闭包。如果传递给mapValues的闭包有副作用,这是危险的。请看下面的要点以获取示例:我看不出这是如何优于其他两种解决方案的。它所做的事情既不明显,也不简洁。这可能是因为它们懒惰/在您对接受的答案发表评论时返回地图上的视图吗?