Kotlin中有条件地组合Lambda以进行多个谓词过滤

问题描述 投票:0回答:1

假设我有以下谓词作为Villager POJO的预定义lambda。

    val matchesSearch: (Villager, String) -> Boolean =
        { villager: Villager, query: String -> villager.name.contains(query) }

    val matchesGender: (Villager, Int) -> Boolean =
        { villager: Villager, filter: Int -> filter == villager.gender }

    val matchesPersonality: (Villager, Int) -> Boolean =
        { villager: Villager, filter: Int -> filter == villager.personality }

    val matchesSpecies: (Villager, Int) -> Boolean =
        { villager: Villager, filter: Int -> filter == villager.species }

    val matchesHobby: (Villager, Int) -> Boolean =
        { villager: Villager, filter: Int -> filter == villager.hobby }

我只想在满足特定条件的情况下应用谓词。例如,如果已应用性别过滤器,则仅按性别过滤。或者,如果输入了一个查询,我只想与搜索查询匹配。

fun getVillagersThatMatchQueryAndFilters(list: List<Villager>): List<Villager> {

    val conditions = ArrayList<Predicate<Villager>>()

    if (searchQuery.isNotEmpty()) {
        // TODO: apply the matchesSearch() predicate lambda
        conditions.add(Predicate { villager -> villager.name.contains(query) })
    }
    if (genderFilter > 0) {
        // TODO: apply the matchesGender() predicate lambda
        conditions.add(Predicate { genderFilter == villager.gender })
    }
    if (personalityFilter > 0) {
        // TODO: apply the matchesPersonality() predicate lambda
        conditions.add(Predicate { personalityFilter == villager.personality })
    }
    if (speciesFilter > 0) {
        // TODO: apply the matchesSpecies() predicate lambda
        conditions.add(Predicate { speciesFilter == villager.species })
    }
    if (hobbyFilter > 0) {
        // TODO: apply the matchesHobby() predicate lambda
        conditions.add(Predicate { hobbyFilter == villager.hobby })
    }

    return list.filter {
        // TODO: match on all conditionally applied predicates
        conditions.allPredicatesCombinedWithAnd() // this doesn't actually exist
    }
}

[以前,我在每个条件下都完成了list.filter{ }并应用了必要的谓词,但是,由于我最多可以应用5个谓词,因此每次调用.filter()都会在列表中进行迭代,因此性能非常糟糕。 。

是否可以通过编程方式遍历List<Predicate<T>>并将谓词与.and()&&组合在一起,以便我可以一次应用过滤器?否则,该如何有条件地合并这些谓词?

我将使用使用herePredicates.stream()的最终Java示例Collectors,但它需要Android API级别24(高于我当前的Android分钟)。

android kotlin filter predicate
1个回答
0
投票

具有all扩展功能,并且同样值得关注的是any扩展功能。我认为您只需要在谓词的过滤器块中使用它们即可。这是一个非常简单的示例,包含一组愚蠢的谓词:

fun main() {
    val thingsToFilter = listOf(-1,2,5)

    val predicates = listOf(
        { value: Int -> value > 0 },
        { value: Int -> value > 4 }
    )

    val filtered = thingsToFilter.filter {candidate ->
        // Get a list of booleans from predicates. Check all of them are true.
        predicates.map { it(candidate) }.all { it }
    }

    print(filtered) // Outputs [5]

}
© www.soinside.com 2019 - 2024. All rights reserved.