scala - 是否可以在 Scala 中使用模式匹配来复制“exists”方法的行为?
问题描述
假设我有一个Seq(1, 2, 3, 4, 5)
并且我想知道其中是否存在值“4”。我想知道是否可以仅使用模式匹配找到并提取答案。
Seq(1, 2, 3, 4, 5) match {
case Seq(_, 4, _*) => true
case _ => false
}
像这样的 match 子句只有在我们指定值的位置已知时才有效。我很想知道是否可以在 Scala 中执行此操作,我是 Scala 新手,并不完全熟悉它的语法和功能。
显然使用 if gaurd 没有帮助,因为它不允许将值提取到变量中。
您可能会问为什么它甚至很重要,为什么不使用当前现有的exists
或filter
方法。想象一下下面的情况。
case class Score(eventName: String, amount: Integer)
case class Person(name: String, scores: Seq[Score])
假设我有一个Person
s 集合,我想找到某个事件的最高分。一个人可能有该事件的分数,也可能没有。
persons.collect({
case x @ _ if x.scores.exists(_.eventName == "event1") =>
x.scores.find(_.eventName == "event1").get.amount
}).max
问题是过滤器eventName
被处理了两次。
我知道可以使用多次迭代filter
来做到这一点。map
但我很想知道是否有使用模式匹配的解决方案,通过模式匹配,您可以同时找到并将值提取到变量中。
解决方案
您可以使用以下方法编写自定义匹配器unapply
:
case class EventScore(eventName: String) {
def unapply(person: Person): Option[Int] =
person.scores.collectFirst { case s if s.eventName == eventName => s.amount }
}
val score = EventScore("event1")
persons.collect({
case score(amount) => amount
}).max
推荐阅读
- mysql - 无法连接到在 docker 中运行的 MySQL
- javascript - 如何在 javascript 中使用集合并获得相同的结果
- d3.js - d3.scaleLog 以 2 为底的刻度
- python - 是否可以设置 lint 自定义设置并忽略 pylance
- c++ - 时间:2019-05-10 标签:c++vector
标题是一个字符串 - javascript - Discord.js 不播放 youtube 网址
- javascript - javascript对象赋值占用了多少内存
- shell - Python 脚本通过 os.system() 退出代码 256 而不是 1 调用 shell 脚本。为什么?
- node.js - Nodejs请求承诺结合来自2个链接的json api数据?
- python - List-2 > sum13 编码 bat 问题:'int' 对象不可迭代