Filter over List with dynamic filter parameter
scala
Solution
Basically what you want is a way to compose predicates. A predicate in this case is a function that takes an User and returns a Boolean. So the type is just User => Boolean
First of all, I would reformulate your "predicate generator methods" so that you can generate predicates. Inside some helper object:
object UserPredicates {
def lastNameEquals(value:String)(user:User) = user.lastName == value
def firstNameStartsWith(value:String)(user:User) = user.firstName.startsWith(value)
..
}
To generate the predicate firstName starts with "H", you can partially apply the firstNameStartsWith method like so:
import UserPredicates._
val p1: User => Boolean = firstNameStartsWith("H")
Then it is pretty simple to create a predicate from multiple predicates by defining methods that compose predicates. Maybe also inside UserPredicates:
def and(predicates:Seq[User => Boolean])(user:User) = predicates.forall(predicate => predicate(user))
def or(predicates:Seq[User => Boolean)(user:User) = predicates.exists(predicate => predicate(user))
Then you can do
import UserPredicates._
val condition1 = firstNameStartsWith("H")
val condition2 = lastNameEquals("Schmidt")
val combined = and(Seq(condition1, condition2))
users.filter(combined)
Or short
users.filter(and(firstNameStartsWith("H"), lastNameEquals("Schmidt")))
.
By the way: you should not use new to create case class instances. Also, you don't have to use equals to compare strings. The scala == operator will call equals and not just check for reference equality like the java == operator.
Problem
If I had a ``` case class User(var firstName: String, var lastName: String, var city: String) ``` and a list ``` val users = List( new User("Peter", "Fox", "Berlin"), new User("Otto", "Schmidt", "Berlin"), new User("Carl", "Schmidt", "Berlin"), new User("Hans", "Schmidt", "Berlin"), new User("Hugo", "Schmidt", "Berlin")) ``` define something ``` val test1 = (user:User,key:String) => user.lastName.equals(key) val test2 = (user:User,key:String) => user.firstName.startsWith(key) ``` and filter ``` val test = users.filter(u => { test1(u,"Schmidt") && test2(u,"H") }) ``` This works fine. But How can I generate something that filters test1, test2 ... testn dynamicly form maybe a list? I want to have a lot of filter conditions predefined and combine them to one condition (like test1(u,"Schmidt") && test2(u,"H")) to filter my list and combine the order of filtering.