2017-02-09 65 views
0

我有一个下面的斯卡拉特质列表。如何将列表分成两个,一个只包含ValidatedSbcCommand对象,另一个只包含FailedValidationSbcCommand对象?基于匹配模式的单独的scala列表

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

,最简单的方法就是打电话'collect'两次,一次为每个类型。除非你正在写3D着色器或其他东西,否则没关系。 –

回答

1

使用列表上的partition方法。它需要一个谓词并产生一个(List, List)第一个列表是真实的情况,第二个是错误的。

+0

不保留子类型信息 – richs

+0

您可以将列表转换为适当的类型。 – puhlen

+0

你*可以*,但在Scala中投射总是一个坏主意,而且几乎总是不必要的。 – Vidya

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列表。

1

我更喜欢使用partition模式匹配。鉴于listList[SbcCommandorOrValidationError]型的,并且只包含ValidatedSbcCommand S和FailedValidationSbcCommand S,你可以这样做:

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

,其中第一清单所有ValidatedSbcCommand S和第二个是所有这将返回(List[SbcCommandorOrValidationError], List[SbcCommandorOrValidationError])类型的元组FailedValidationSbcCommand s。

如果您以后需要访问特定的子类,请不要投射。使用模式如上匹配:除非你确信你不能做对列表两遍

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