我建议使用foldLeft 来执行此操作:
val m: Map[Int, String] = Map(1 -> "a", 2 -> "b", 3 -> "c", 4 -> "d")
m: Map[Int,String] = Map(1 -> a, 2 -> b, 3 -> c, 4 -> d)
m.foldLeft(Map.empty[String, String]) {
case (accum, (i, s)) if i % 2 == 0 => accum + ("even" -> accum.get("even").fold(s)(existing => existing + s))
case (accum, (i, s)) => accum + ("odd" -> accum.get("odd").fold(s)(existing => existing + s))
}
//scala.collection.immutable.Map[String,String] = Map(odd -> ac, even -> bd)
编辑:
我有很多案例,而不仅仅是“偶数”和“奇数”。如果我想以 1000 为模怎么办,所以有 1000 个不同的组。我无法在 foldLeft 函数中将它们全部列举为案例。有没有更通用的方法来做到这一点?
为了概括这一点,我们只需要使用比“偶数”或“奇数”更好的键。在这种情况下,听起来密钥将基于i。因此,让我们仅以模块 10 为例来避免大型控制台打印输出。让我们用一堆东西制作一张新地图:
import scala.util.Random
val testMap = (0 to 30).map(i => i -> Random.alphanumeric.filter(_.isLetter).take(Random.nextInt(3)).mkString("")).toMap
这可以使我们的每个条目的每个地方都有一些随机字母的示例地图。
然后它实际上只有一次,因为我们的键控功能现在只是 i 本身模块 10。
testMap.foldLeft(Map.empty[Int, String]) {
case (accum, (i, s)) => accum + (i % 10 -> accum.get(i % 10).fold(s)(existing => existing + s))
}
或者,为了让事情更明显:
testMap.foldLeft(Map.empty[Int, String]) {
case (accum, (i, s)) => {
val key = i % 10
accum + (key -> accum.get(key).fold(s)(existing => existing + s))
}
}
这是一个示例运行:
testMap: scala.collection.immutable.Map[Int,String] = Map(0 -> q, 5 -> Ax, 10 -> a, 24 -> AX, 25 -> "", 14 -> U, 20 -> "", 29 -> R, 1 -> hB, 6 -> ky, 28 -> ch, 21 -> dk, 9 -> v, 13 -> BR, 2 -> R, 17 -> "", 22 -> h, 27 -> "", 12 -> "", 7 -> "", 3 -> "", 18 -> "", 16 -> Qu, 11 -> XO, 26 -> gS, 23 -> "", 8 -> "", 30 -> fn, 19 -> "", 4 -> "", 15 -> Br)
res6: scala.collection.immutable.Map[Int,String] = Map(0 -> fn, 5 -> Br, 1 -> XO, 6 -> gS, 9 -> "", 2 -> "", 7 -> "", 3 -> "", 8 -> "", 4 -> U)
scala> testMap.foldLeft(Map.empty[Int, String]) {
| case (accum, (i, s)) => accum + (i % 10 -> accum.get(i % 10).fold(s)(existing => existing + s))
| }
res7: scala.collection.immutable.Map[Int,String] = Map(0 -> qafn, 5 -> AxBr, 1 -> hBdkXO, 6 -> kyQugS, 9 -> Rv, 2 -> Rh, 7 -> "", 3 -> BR, 8 -> ch, 4 -> AXU)