简体   繁体   English

Scala模式匹配 - 匹配多个成功案例

[英]Scala pattern matching - match multiple successful cases

I am fairly new to Scala, and would like to know if it is possible for a match to execute multiple matching cases at once. 我对Scala相当新,并且想知道match是否可以同时执行多个匹配的情况。 Without getting into too much detail, I am basically working on a function that "scores" a certain piece of text according to various traits; 在没有深入细节的情况下,我基本上致力于根据各种特征“评分”某段文字的功能; these traits can overlap, and multiple traits can be true for one given string. 这些特征可以重叠,并且对于一个给定的字符串,多个特征可以为真。

To illustrate what I want in code, it would look something like this: 为了说明我想要的代码,它看起来像这样:

Say we have a String, str , with a value of "Hello World". 假设我们有一个String, str ,其值为“Hello World”。 I would like something along the lines of the following: 我想要的是以下几点:

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

I would like the above code to trigger both the first and third conditions, effectively returning both 2 and 3 (as a tuple or in any other way). 我想上面的代码,以触发所述第一和第三个条件,有效地返回既2和3(作为一个元组或以任何其他方式)。

Is this possible? 这可能吗?

Edit: I know this can be done with a chain of if 's, which is the approach I took. 编辑:我知道这可以通过一系列if来完成,这就是我采用的方法。 I'm just curious if something like the above implementation is possible. 我很好奇是否可以实现上述实现。

You can turn your case statements to functions 您可以将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

You can filter the 0 values with filter 您可以过滤与0值filter

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

Please, consider this solution: 请考虑这个解决方案:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM