Объединение типа функции в Kotlin с 'или' - PullRequest
0 голосов
/ 18 апреля 2020

Я довольно новичок в Kotlin и подумал, можно ли объединить список типа функции в одну функцию.

У меня есть интерфейс, представляющий фильтр, и некоторые предопределенные фильтры:

interface Filter : (Int) -> Boolean {
    val a: Int
}

class FilterA(override val a: Int) : Filter {

    override fun invoke(numberToFilter: Int): Boolean {
        ....
    }
}

class FilterB(override val a: Int) : Filter {

    override fun invoke(numberToFilter: Int): Boolean {
        ....
    }
}

Теперь у меня есть список Filter объекта, который я хочу объединить с помощью включающей дизъюнкции OR, чтобы я мог передать это фильтру списка Int , Например:

val combinedFilter = listOf(FilterA(a), FilterB(b)). { `do something here` }

val filteredInt = listToBeFiltered.filter { combinedFilter }

Однако я как-то застрял в определении части do something here. Я полагаю, что вы можете использовать уменьшение метод, чтобы сделать это, но он продолжает сообщать мне ошибку как-то. Ниже описано, как я это попробовал

val combinedFilter = listOfFilters.reduce { filterA, filterB -> { filterA or filterB } }

infix fun <T> ((T) -> Boolean).or(that: (T) -> Boolean): (T) -> Boolean = { this(it) || that(it) }

Но получил

Type mismatch.
Required:
Filter
Found:
() → (Int) → Boolean

Мне кажется, я что-то не так сделал с синтаксисом. Надеюсь, что вы, ребята, можете помочь. Спасибо.

1 Ответ

1 голос
/ 18 апреля 2020

Это потому, что вы завернули выражение в дополнительную лямбду, также тип аккумулятора в reduce будет Filter для вашего listOfFilters, но or возвращает (T) -> Boolean. Это можно исправить, указав тип аккумулятора и избавившись от дополнительной лямбды:

val combinedFilter = listOfFilters.reduce<(Int) -> Boolean, Filter> { filterA, filterB -> filterA or filterB }

Но есть лучший способ сделать это без выделения большого количества лямбд:

val combinedFilter = { x: Int -> listOfFilters.any { filter -> filter(x) } }
val filteredInt = listToBeFiltered.filter(combinedFilter)

или

fun <T> List<(T) -> Boolean>.combineAny() = { x: T -> this.any { filter -> filter(x) } }
val combinedFilter = listOfFilters.combineAny()
val filteredInt = listToBeFiltered.filter(combinedFilter)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...