如何解决将自动递增的值添加到空值的 Scala 映射
我有如下 Scala 地图:
val mapData = Map(AA1 -> 1,AA2 -> 2,AA3 -> null,AA4 -> null)
val maxValue = mapData.valuesIterator.max
我想遍历此地图,如果值为 null
,则使用从最高地图值开始的自动递增值替换该值(在上面的地图中为 2
)。结果应该如下所示。顺序不重要。
Map(AA1 -> 1,AA3 -> 3,AA4 -> 4)
我尝试使用 mapData.map()
但我无法在地图操作期间保留递增的值。 Scala 中还有其他方法可以实现这一点吗?
解决方法
首先,您提供的代码片段无法编译,因为值和键中的 Null
未在引号中交换以被视为字符串。我已经用 Option
替换了值:
val mapData: Map[String,Option[Int]] = Map("AA1" -> Some(1),"AA2" -> Some(2),"AA3" -> None,"AA4" -> None)
val max = mapData.values.flatten.max
val (result,_) = mapData.toList.foldLeft(Map.empty[String,Int] -> (max + 1)) {
case ((accumulator,nextMax),(key,None)) =>
((accumulator + (key -> nextMax)),nextMax + 1)
case ((accumulator,Some(value))) =>
((accumulator + (key -> value)),nextMax)
}
println(result)
将打印下一个结果:Map(AA1 -> 1,AA2 -> 2,AA3 -> 3,AA4 -> 4)
斯卡蒂示例:https://scastie.scala-lang.org/ltmhh3tuQCWf2deaLboK9w
更新:
正如@Tomer Shetah 在评论部分正确指出的那样 - max
不安全,因为 List[Int].empty.max
会抛出异常。替换为 maxOption
val mapData: Map[String,"AA4" -> None)
val max = mapData.values.flatten.maxOption.getOrElse(0) //safer with maxOption
val (result,nextMax)
}
println(result)
斯凯蒂:https://scastie.scala-lang.org/iiSvahIZStyL1MDi0Glsvg
,这是一种基本方法,但可能不是优化方法。
var mapData = Map("AA1" -> 1,"AA2" -> 2,"AA3" -> null,"AA4" -> null)
val nonNull = mapData.values.filter(_ != null)
val max = nonNull.map(_.toString.toInt).max
var nullCount = mapData.count(_._2==null)
mapData=mapData.map(t => {
if (t._2 == null) {
val output = (t._1,max + nullCount)
nullCount -= 1
output
}
else (t._1,t._2)
})
println(mapData)
//output : Map(AA1 -> 1,AA3 -> 4,AA4 -> 3)
,
您的另一个选择是:
val startFrom = mapData.values.filter(_.isInstanceOf[Int]).map(_.asInstanceOf[Int]).maxOption.getOrElse(0) + 1
val values = LazyList.from(startFrom).iterator
val result = mapData.view.mapValues {
case x: Int => x
case null => values.next()
case _ => ???
}
请注意,result
未具体化。您需要调用 .toMap
来实现它。
代码运行于 Scastie
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。