在 Scala 中递归求和地图的正确方法
Correct Approach to Recursively Summing Map in Scala
我刚刚开始了一个项目,我们正在将一些 C# 工具迁移到一个新的 Scala 项目。这是我第一次接触这种语言(以及一般的函数式编程),所以为了不只是在 Scala 中编写 Java 风格的代码,我想知道处理以下场景的正确方法是什么。
我们有两个地图对象,它们表示具有以下结构的表格数据:
map1 key|date|mapping val
map2 key|number
第一个对象中的映射值并不总是被填充。目前这些由 Map[String, Array[String]]
和 Map[String, Double]
类型表示。
在 C# 工具中,我们有以下方法:
- 遍历第一个映射中设置的键
- 对于每个键,检查映射值是否为空
- 如果没有映射,则从映射 2 和 return
中获取数字
- 如果存在映射,则递归调用方法以获取完整范围的映射值及其编号,边走边求和。例如。键 1 可能映射到键 4,键 4 可能映射到键 5 等,我们想在 map2 中对这些键的所有值求和。
在 Scala 中是否有一种聪明的方法可以避免从 for 循环中更新列表并递归遍历地图?
这就是你想要的吗?
@annotation.tailrec
def recurse(key: String, count: Double, map1: Map[String, String], map2: Map[String, Double]): Double = {
map1.get(key) match {
case Some(mappingVal) if mappingVal == "" =>
count + map2.getOrElse(mappingVal, 0.0)
case Some(mappingVal) =>
recurse(mappingVal, count + map2.getOrElse(mappingVal, 0.0), map1, map2)
case None => count
}
}
使用示例:
val m1: Map[String, String] = Map("1" -> "4", "4" -> "5", "5" -> "6", "8" -> "")
val m2: Map[String, Double] = Map("1" -> 1.0, "4" -> 4.0, "6" -> 10.0)
m1.map {
case (k, _) => k -> recurse(k, 0.0, m1, m2)
}.foreach(println)
输出:
(1,14.0)
(4,10.0)
(5,10.0)
(8,0.0)
请注意,没有循环检测 - 如果 map1 有循环,这将永远不会终止。
我刚刚开始了一个项目,我们正在将一些 C# 工具迁移到一个新的 Scala 项目。这是我第一次接触这种语言(以及一般的函数式编程),所以为了不只是在 Scala 中编写 Java 风格的代码,我想知道处理以下场景的正确方法是什么。
我们有两个地图对象,它们表示具有以下结构的表格数据:
map1 key|date|mapping val
map2 key|number
第一个对象中的映射值并不总是被填充。目前这些由 Map[String, Array[String]]
和 Map[String, Double]
类型表示。
在 C# 工具中,我们有以下方法:
- 遍历第一个映射中设置的键
- 对于每个键,检查映射值是否为空
- 如果没有映射,则从映射 2 和 return 中获取数字
- 如果存在映射,则递归调用方法以获取完整范围的映射值及其编号,边走边求和。例如。键 1 可能映射到键 4,键 4 可能映射到键 5 等,我们想在 map2 中对这些键的所有值求和。
在 Scala 中是否有一种聪明的方法可以避免从 for 循环中更新列表并递归遍历地图?
这就是你想要的吗?
@annotation.tailrec
def recurse(key: String, count: Double, map1: Map[String, String], map2: Map[String, Double]): Double = {
map1.get(key) match {
case Some(mappingVal) if mappingVal == "" =>
count + map2.getOrElse(mappingVal, 0.0)
case Some(mappingVal) =>
recurse(mappingVal, count + map2.getOrElse(mappingVal, 0.0), map1, map2)
case None => count
}
}
使用示例:
val m1: Map[String, String] = Map("1" -> "4", "4" -> "5", "5" -> "6", "8" -> "")
val m2: Map[String, Double] = Map("1" -> 1.0, "4" -> 4.0, "6" -> 10.0)
m1.map {
case (k, _) => k -> recurse(k, 0.0, m1, m2)
}.foreach(println)
输出:
(1,14.0)
(4,10.0)
(5,10.0)
(8,0.0)
请注意,没有循环检测 - 如果 map1 有循环,这将永远不会终止。