json - Scala - 当需要跳过没有默认值的不存在的键时,如何处理在 Map 中找不到的键?
问题描述
我有一组字符串并将其用作键值以从 Map 中获取 JValues:
val keys: Set[String] = Set("Metric_1", "Metric_2", "Metric_3", "Metric_4")
val logData: Map[String, JValue] = Map("Metric_1" -> JInt(0), "Metric_2" -> JInt(1), "Metric_3" -> null)
在下面的方法中,我正在解析每个指标的值。首先获取所有值,然后过滤以去除空值,然后将现有值转换为布尔值。
val metricsMap: Map[String, Boolean] = keys
.map(k => k -> logData(k).extractOpt[Int]).toMap
.filter(_._2.isDefined)
.collect {
case (str, Some(0)) => str -> false
case (str, Some(1)) => str -> true
}
当在地图keys
中找不到其中一个时,我遇到了问题。logData
所以我得到一个java.util.NoSuchElementException: key not found: Metric_4
.
在这里,我extractOpt
用于从 JSON 中提取值并且不需要默认值。所以可能extractOrElse
不会有帮助,因为我只需要获取现有键的值并跳过不存在的键。
logData
当Map中不存在密钥时,处理这种情况的正确方法是什么?
UPD:我已经达到了预期的结果.map(k => k -> apiData.getOrElse(k, null).extractOpt[Int]).toMap
。但是仍然不确定这是最好的方法。
解决方案
值是 JSON 是一个红鲱鱼 - 这是引发异常的缺失键。有一个方法被调用get
,它从包裹在一个选项中的映射中检索一个值。如果我们使用Int
s 作为我们拥有的值:
val logData = Map("Metric_1" -> 1, "Metric_2" -> 0, "Metric_3" -> null)
keys.flatMap(k => logData.get(k).map(k -> _)).toMap
> Map(Metric_1 -> 1, Metric_2 -> 0, Metric_3 -> null)
使用flatMap
而不是map
意味着打开Some
结果并删除None
s。现在,如果我们回到您的实际示例,我们有另一个图层,该 flatMap 将消除该Metric_3 -> null
项目:
keys.flatMap(k => logData.get(k).flatMap(_.extractOpt[Int]).map(k -> _)).toMap
您还可以使用推导式重写它for
:
(for {
k <- keys
jv <- logData.get(k)
v <- jv.extractOpt[Int]
} yield k -> v).toMap
我使用Success
andFailure
代替 JSON 值以避免必须使用 json4s 设置 shell 来制作示例:
val logData = Map("Metric_1" -> Success(1), "Metric_2" -> Success(0), "Metric_3" -> Failure(new RuntimeException()))
scala> for {
| k <- keys
| v <- logData.get(k)
| r <- v.toOption
| } yield k -> r
res2: scala.collection.immutable.Set[(String, Int)] = Set((Metric_1,1), (Metric_2,0))
推荐阅读
- android - 除非清除 ram,否则无法将数据持久保存在 Room 数据库中
- python - Python RGB 到灰度转换(ExGG)矩阵运算
- scala - 窗口上的 Spark 3 类型化用户定义聚合函数
- c++ - 如何声明和定义将返回编译时未知的少数自定义类之一的函数?
- java - Spring验证器Validator的目标无效
- kotlin - Android LiveData Room 引用的实体实体在活动转换后未更新
- python - 詹金斯:如何在构建中获取当前时间并将其传递给构建后
- java - Java servlet 重定向
- javascript - 如何根据开关滑块位置更改不透明度?
- laravel - 名称、地址和图像等数据字段正在插入到数据库中,但问题是图像没有存储到文件夹中