What i'm trying to achieve is using a filter function with dynamic predicates. What I did so far is creating a function that choose the best predicate:
fun buildDatePredicate(dateFrom: LocalDate?, dateTo: LocalDate?): Predicate<MyClass> {
if (dateFrom != null && dateTo == null) {
return Predicate { myItem -> myItem.date.isAfter(dateFrom) }
}
if (dateTo != null && dateFrom == null) {
return Predicate { myItem -> myItem.date.isBefore(dateTo) }
}
if (dateTo != null && dateFrom != null) {
return Predicate { myItem ->
myItem.date.isBefore(dateTo) && myItem.date.isAfter(dateFrom)
}
}
return Predicate { true }
}
And then I tried to use filter on my list using that Predicate
myList.filter { buildDatePredicate(fromDate.toLocalDate(),toDate.toLocalDate()) }
But it does not works due to
Type mismatch.
Required:
Boolean
Found:
Predicate<MyClass>
Is it possible to achieve what i'm trying to do?
Thanks
CodePudding user response:
A simple solution is to just call the test
-method on the predicate:
myList.filter {
val pred = buildDatePredicate(fromDate.toLocalDate(), toDate.toLocalDate())
pred.test(it)
}
But a more idiomatic solution in Kotlin is to not use java.util.function.Predicate
, but rather a function of type (MyClass) -> Boolean
. Then you can just pass the result of buildDatePredicate
directly to the filter function. Like this:
fun buildDatePredicate(dateFrom: LocalDate?, dateTo: LocalDate?): (MyClass) -> Boolean {
if (dateFrom != null && dateTo == null) {
return { myItem -> myItem.date.isAfter(dateFrom) }
}
if (dateTo != null && dateFrom == null) {
return { myItem -> myItem.date.isBefore(dateTo) }
}
if (dateTo != null && dateFrom != null) {
return { myItem ->
myItem.date.isBefore(dateTo) && myItem.date.isAfter(dateFrom)
}
}
return { true }
}
And then call it with:
myList.filter(buildDatePredicate(fromDate.toLocalDate(), toDate.toLocalDate()))