java - Scala - 模式匹配布尔值和默认值时无法访问的代码
问题描述
我有一个Map[String, Boolean]
包含各种 Metrics 数据和一个单独Seq[String]
的包含metricKeys
.
问题是 Map 可能不包含所有内容,metricKeys
但我还需要保留有关不存在值的信息。我试图通过使用来解决这个问题.getOrElse
。我预计List[String]
带有度量值的结果将包含“Y”代表值true
,“N”代表值false
和“”代表null
值。
但是我收到一个警告:unreachable code case _ => StringUtils.EMPTY
。什么是正确匹配默认值的正确方法?
def parseMetrics(metric: Metric): List[String] = {
import scala.collection.JavaConverters._
val metricKeys: Seq[String] = getMetricKeys
val matricsData = metric.transactionMap.asScala
metricKeys.map(key => key -> matricsData.getOrElse(key, null))
.toMap.values.map(Predef.Boolean2boolean).collect {
case true => "Y"
case false => "N"
case _ => StringUtils.EMPTY
}.toList
}
解决方案
我假设这是对这个问题的跟进,并且matricsData
有一个类似的类型Map[String, java.lang.Boolean]
?
那么问题是当它的参数是 时,Predef.Boolean2boolean
从装箱 Java 布尔值到 Scala 布尔值的转换会返回,所以如果你想区分 true、false 和的值,你需要在转换之前进行(无论是否转换是明确的,就像这里一样)。false
null
null
java.lang.Boolean
但是,有更好的方法来解决这个问题,如下所示:
metricKeys.map { key =>
matricsData.get(key) match {
case Some(value) => if (value) "Y" else "N"
case None => StringUtils.EMPTY
}
}
或者使用fold
onOption
而不是模式匹配:
metricKeys.map { key =>
matricsData.get(key).fold(StringUtils.EMPTY) { value =>
if (value) "Y" else "N"
}
}
或者先转换映射值,然后查找所有键:
val asYN: Map[String, String] = matricsData.mapValues { value =>
if (value) "Y" else "N"
}
metricKeys.map(key => asYN.getOrElse(key, StringUtils.EMPTY))
您选择哪种方法取决于个人喜好,但其中任何一种方法都比使用盒装 Java 布尔值对某种三向真假或缺失数据建模要好。
推荐阅读
- python - Pandas - 当 N 存储在一列中时,新列基于另一列 N 行的值
- python - 在灯上重置计时器
- javascript - HTML javascript 表单 - 我可以通过哪些其他方式使用表单验证来编写这个 javascript 函数
- python - 如何在多个文件夹中创建多个csv文件
- cygwin - cygwin rbenv ruby-build 损坏的 irb 用于多个版本
- python - 如何将我的主窗口链接到一个对话框,以便当我选择 File -> New 时,我的“新事物”对话框打开?
- sql - 谷歌表格查询功能。我怎样才能只获得唯一或不同的行?
- macos - 如何在 Mac 上更改智能文件夹中的搜索范围?
- docker - 如何连接到在 Docker 上运行的 Rust 服务器应用程序
- ruby-on-rails - Rails ActiveRecord 返回与数据库不同的结果