基于匹配模式单独的scala列表

时间:2017-02-09 16:18:59

标签: scala

我有以下scala特征的列表。如何将列表分成两个,一个只包含ValidatedSbcCommand对象,另一个只包含FailedValidationSbcCommand对象?

sealed trait SbcCommandorOrValidationError 
case class ValidatedSbcCommand(sbcCommand: SbcCommand) extends SbcC  ommandorOrValidationError
case class FailedValidationSbcCommand(sbcCommandError: SbcCommandError) extends SbcCommandorOr

4 个答案:

答案 0 :(得分:1)

在列表中使用partition方法。它需要一个谓词并产生一个(List, List)第一个列表用于真实情况,第二个列表用于假。

答案 1 :(得分:1)

 val result = originalList.foldRight(Tuple2(List[ValidatedSbcCommand](), List[FailedValidationSbcCommand]())){ (start, rest) =>
        start match {
          case a:ValidatedSbcCommand => (a::rest._1, rest._2)
          case b:FailedValidationSbcCommand => (rest._1, b::rest._2)
          case _ => rest
        }
    }

然后result._1将为您提供ValidatedSbcCommand的列表,result._2将为您提供FailedValidationSbcCommand的列表。

答案 2 :(得分:1)

我更喜欢使用partition进行模式匹配。鉴于list类型为List[SbcCommandorOrValidationError]并且仅包含ValidatedSbcCommandFailedValidationSbcCommand,您可以这样做:

val (validatedCommands, failedCommands) = list.partition {
  case command: ValidatedSbcCommand => true
  case _ => false
}

这将返回(List[SbcCommandorOrValidationError], List[SbcCommandorOrValidationError])类型的元组,其中第一个列表是ValidatedSbcCommand个,第二个列表是FailedValidationSbcCommand个。

如果以后需要访问特定的子类,请不要强制转换。使用上述模式匹配:

validatedCommands.map { 
  case c: ValidatedSbcCommand => functionTakingValidatedSbcCommandsOnly(c) 
}

答案 3 :(得分:0)

从Scala 2.13开始,您可以使用partitionMap,它可以完全满足您的要求,并保留子类型信息:

 list partitionMap {
    case v: ValidatedSbcCommand => Left(v)
    case f: FailedValidationSbcCommand => Right(f)
 }