如何从scala中的列表中按类型查找项目?

时间:2014-04-14 02:27:25

标签: scala

说我已定义:

sealed trait ValidationResult
object Valid extends ValidationResult
case class Invalid(error:String) extends ValidationResult

然后我有一个包含一些验证结果的列表:

val results = List(Valid, Invalid("required username"), Valid)

我想找到第一个类型为Invalid的人:

results.find( ??? ) match {
    case Some(error) => println("Invalid: " + error)
    case _ => println("No error")
}

您可以看到???中有find,但我不知道该在那里输入什么。

2 个答案:

答案 0 :(得分:7)

results.find {
  case Invalid(_) => true
  case _ => false
} match {
  case Some(Invalid(error)) => println("Invalid: " + error)
  case _ => println("No error")
}

或者也许:

results.collectFirst {
  case Invalid(error) => error
} match {
  case Some(error) => println("Invalid: " + error)
  case _ => println("No error")
}

不需要,但我会将Valid转换为case对象,以防你想要进行模式匹配。

注意:两个版本都会返回找到的第一个错误。如果你想积累错误,那么你需要过滤和映射(或折叠)。

答案 1 :(得分:0)

使用列表span

val (v,inv) = results.span { _ match { 
    case Invalid(_) => false  
    case _ => true 
  } 
}

返回

(v, inv) = (List(Valid),
            List(Invalid(required username), Valid))

在结果对中,

  • 第一个元素是列表开头的所有有效结果列表
  • 第二个元素是一个以不包含谓词的第一个项目开头的列表。

因此我们可以用

提取第一个无效项目
if (inv.isEmpty) 
  Valid 
else 
  inv.head

res: Invalid(required username)