如何使用谓词在Kotlin中过滤

发布于 2025-02-13 22:19:18 字数 937 浏览 2 评论 0原文

我要实现的目标是使用具有动态谓词的过滤器函数。 到目前为止,我所做的是创建一个选择最佳谓词的函数:

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 }
}

然后我尝试使用该谓词在列表上使用过滤器,

myList.filter { buildDatePredicate(fromDate.toLocalDate(),toDate.toLocalDate()) }

但它无法正常工作

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

但是由于可以实现我要做的事情,

?谢谢

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

打小就很酷 2025-02-20 22:19:18

一个简单的解决方案是在谓词上只调用test -Method:

myList.filter { 
    val pred = buildDatePredicate(fromDate.toLocalDate(), toDate.toLocalDate())
    pred.test(it)
}

但是Kotlin中更惯用的解决方案是不使用java.util.function.function.predicate.predicate,而是类型(myClass)的函数 - &gt;布尔值。然后,您只需将builddatePredicate的结果直接传递到过滤器函数即可。这样:

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 }
}

然后将其称为:

myList.filter(buildDatePredicate(fromDate.toLocalDate(), toDate.toLocalDate()))

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()))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文