我有一系列数据要转换成一对 Map ;每个 Map 代表原始序列的单独转换 . 我可以生成元组,这些元组将在原始输入序列的单个传递中组成每个映射,如下所示:
val entries: Seq[((A, B), (A, C))] = input map { x =>
val key = genKey(x)
val tuple1 = key -> f(x)
val tuple2 = key -> g(x)
}
我可以通过遍历生成的seq两次单独创建每个 Map ,如下所示:
val map1 = (entries map { case(e1, _) => e1 }).toMap
val map2 = (entries map { case(_, e2) => e2 }).toMap
我认为可能有一种方法可以在 Map 上的一次传递中完成整个转换,这样我就可以做到这样的事情:
val (map1, map2) = (entries accumulate { case(e1, e2) => // add e1 to map1, add e2 to map2 })
foldLeft可能会这样做,但也许有更优雅的东西?
3 回答
使用标准库:
Scalaz是一个单行:
但是,这两种解决方案都将创建两个额外的中间序列 . 这可能不是你需要担心的事情,但如果你真的想要避免它,折叠实际上并不是那么不优雅:
不需要Scalaz .
如果你想使用上面的
entries
方法,那么显而易见的方法是:但是你仍然(1)遍历你的
inputs
以创建一系列元组,然后(2)再次遍历unzip
,然后(3)遍历s1.toMap
,然后(4)再次在s2.toMap
中遍历 .如果您的问题是最小的遍历,正如您的问题所暗示的那样,您需要手动构建结果 . 优雅,不,但直截了当,你可以取消你的
entries
方法 .这将是我的方法(imho更容易掌握初学者):