Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to filter in kotlin using predicates

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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Type mismatch.
Required:
Boolean
Found:
Predicate<MyClass>

Is it possible to achieve what i’m trying to do?

Thanks

>Solution :

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 pragmatic 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()))
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading