Scala 反转键到值的映射
假设我有一组类Scala 反转键到值的映射,scala,map,Scala,Map,假设我有一组类Action如下:actions:set[Action],每个Action类都有一个val result:set[result],其中result是一个case类 我希望从result到Set[Action]获得一个映射,以确定哪些操作会导致特定的result。显然,由于一个动作可以有多个结果s,因此它可以在地图中出现多个集合 我一直在想办法解决这个问题(我是Scala的新手),想知道我是否可以用map()和groupBy()之类的东西来解决这个问题,但有点不知所措。我不想回到命令
Action
如下:actions:set[Action]
,每个Action
类都有一个val result:set[result]
,其中result
是一个case类
我希望从result
到Set[Action]
获得一个映射,以确定哪些操作会导致特定的result
。显然,由于一个动作
可以有多个结果
s,因此它可以在地图中出现多个集合
我一直在想办法解决这个问题(我是Scala的新手),想知道我是否可以用map()和groupBy()之类的东西来解决这个问题,但有点不知所措。我不想回到命令式编程,特别是如果有一些Scala映射函数可以帮助的话
实现这一点的最佳方法是什么?不太优雅,因为
groupBy
无法处理已在Tuple2
上运行的情况,因此您最终会执行大量的tuplen和untuplen操作:
case class Conseq()
case class Action(conseqs: Set[Conseq])
def gimme(actions: Seq[Action]): Map[Conseq, Set[Action]] =
actions.flatMap(a => a.conseqs.map(_ -> a))
.groupBy(_._1)
.mapValues(_.map(_._2)(collection.breakOut))
第一行“拉链”每个动作及其所有后果,产生一个Seq[(Conseq,action)]
,通过第一个产品元素将其分组,得到Map[Conseq,Seq[(Conseq,action)]
。因此最后一步需要将Map的值从Seq[(Conseq,action)]
转换为Set[action]
。这可以通过mapValues
完成。如果没有显式的生成器工厂,它将生成Seq[Action]
,因此必须编写.mapValues(u.map(u.u 2)).toSet
。将第二个参数列表中的集合传递到map
可以保存一个步骤,并使map
直接生成Set
集合类型
另一种可能是使用嵌套折叠:
def gimme2(actions: Seq[Action]) = (Map.empty[Conseq, Set[Action]] /: actions) {
(m, a) => (m /: a.conseqs) {
(m1, c) => m1.updated(c, m1.getOrElse(c, Set.empty) + a)
}
}
这可能更具可读性。我们从一个空的结果图开始,遍历操作,在内部折叠中遍历每个操作的结果,这些结果被合并到结果图中。谢谢。您介意解释一下每一行发生了什么吗?尤其是最后一行。MultiMap
是一种混合到mutabl中的特性e、 映射[A,Set[B]]
添加一个addBinding(A:A,B:B)
方法,该方法将任意数量的不同B
累积到一个键中。它还添加一个entryExists
方法,允许您查询与给定键关联的集合中是否存在任何单个B
。