cool breeze cool breeze - 1 year ago 53
Scala Question

How to compute a list of validators and return a Seq[String]

I am creating these validators that will accumulate all the error messages.

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( == id) copy(xs = user :: xs) else this
def errors = if(xs.isEmpty) Seq[s"User with id $id was not found"] else Seq.empty

Now what I want to do is, say I have a bunch of these types of Validator classes like

How would I go through all of them given this:

val users: List[User] = loadUsers()
val validators: List[UserValidator] = loadValidators()

How can I loop through each validator and pass in all the users, so that at the end of the computation I have a Seq[String] error messages for all the errors.

Answer Source
validators.flatMap(v =>


val combinations = for {
   v <- validators
   u <- users
} yield v.validate(u)


Both expressions return a List[String]

EDIT: Per clarification of question - now using foldLeft to get each validator run through all users (potentially collecting errors for these users), then collecting all the errors from all these "final" validators using flatMap:

validators.flatMap(v =>
  // folding left, starting with original validator, "aggregating" errors: 
  users.foldLeft(v) { case (v1, u) => v1.validate(u) }.errors