【问题标题】:Scala pattern matching - match multiple successful casesScala模式匹配——匹配多个成功案例
【发布时间】:2015-09-14 08:25:20
【问题描述】:

我是 Scala 的新手,想知道 match 是否可以一次执行多个匹配的案例。没有过多的细节,我基本上正在研究一个根据各种特征“评分”某段文本的功能;这些特征可以重叠,一个给定的字符串可以有多个特征。

为了说明我想要的代码,它看起来像这样:

假设我们有一个字符串str,其值为“Hello World”。我想要以下内容:

str match {
    case i if !i.isEmpty => 2
    case i if i.startsWith("world") => 5
    case i if i.contains("world") => 3
    case _ => 0
}

我希望上面的代码能够触发 both 第一个和第三个条件,有效地返回 2 和 3(作为元组或以任何其他方式)。

这可能吗?

编辑:我知道这可以通过if 的链来完成,这是我采用的方法。我只是好奇是否可以实现上述实现。

【问题讨论】:

  • 就我而言,模式匹配仅适用于第一个正确的情况。
  • @Haito 是的...这就是为什么我想知道是否有任何我不熟悉的方法来制作这样的东西。
  • 不可能。返回类型是什么?您可以使用 List[(String => Boolean, Int)] 之类的东西,然后使用 predicateList.collect {case (p, i) if p(myWordToTest) => i}
  • 我最终选择了((if (!i.isEmpty) 2) :: (if (i.startsWith("world")) 5) :: (if (i.contains("world")) 3) :: Nil) map {case i: Int => i case _ => 0} sum,但想看看是否有更优雅的方式。 @Marth,如果可能的话,我预计返回类型可能是 Tuple

标签: scala pattern-matching


【解决方案1】:

您可以将 case 语句转换为函数

val isEmpty = (str: String) => if ( !str.isEmpty) 2 else 0
val startsWith = (str: String) => if ( str.startsWith("world"))  5  else 0
val isContains = (str: String) => if (str.toLowerCase.contains("world")) 3  else 0

val str = "Hello World"

val ret = List(isEmpty, startsWith, isContains).foldLeft(List.empty[Int])( ( a, b ) =>  a :+ b(str)   )

ret.foreach(println)
//2
//0
//3

你可以用filter过滤0值

 val ret0 = ret.filter( _ > 0)
 ret0.foreach(println)

【讨论】:

    【解决方案2】:

    请考虑这个解决方案:

    val matches = Map[Int, String => Boolean](2 -> {_.isEmpty}, 3 -> {_.contains("world")}, 5 -> {_.startsWith("world")})
    val scores = matches.filter {case (k, v) => v(str)}.keys
    

    【讨论】:

      猜你喜欢
      • 2013-09-13
      • 2017-02-25
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 2017-04-25
      • 2014-08-12
      • 1970-01-01
      相关资源
      最近更新 更多