我正在创建这些验证器,它们将累积所有错误消息。
trait UserValidator {
def validate(user: User): UserValidator
def errors: Seq[String]
}
case class UserIdExistsValidator(id: Int, xs: List[User] = Nil) extends UserValidator {
def validate(user: User) = if(user.id == id) copy(xs = user :: xs) else this
def errors = if(xs.isEmpty) Seq[s"User with id $id was not found"] else Seq.empty
}
现在我要做的是,说我有很多类型的Validator类,如UserIdExistsValidator
。
鉴于此,我将如何完成所有这些:
val users: List[User] = loadUsers()
val validators: List[UserValidator] = loadValidators()
如何循环遍历每个验证器并传入所有用户,以便在计算结束时我有一个Seq [String]错误消息用于所有错误。
答案 0 :(得分:3)
validators.flatMap(v => users.map(v.validate)).flatMap(_.errors)
或:
val combinations = for {
v <- validators
u <- users
} yield v.validate(u)
combinations.flatMap(_.errors)
两个表达式都返回List[String]
修改强>:
每次澄清问题 - 现在使用foldLeft
让每个验证器都通过所有用户运行(可能会为这些用户收集错误),然后从所有这些用户收集所有错误&#34; final&#34;验证者使用flatMap
:
validators.flatMap(v =>
// folding left, starting with original validator, "aggregating" errors:
users.foldLeft(v) { case (v1, u) => v1.validate(u) }.errors
)