I'm pretty new to Kotlin and wondered if you can combine a list of function type into a single function.
I have an interface presents a filter, and some predefined filters:
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 {
....
}
}
I'm now have a list of Filter
object, which I want to combine using inclusive disjunction OR
, so that I can passed that to a filter a list of Int. For example:
val combinedFilter = listOf(FilterA(a), FilterB(b)). { `do something here` }
val filteredInt = listToBeFiltered.filter { combinedFilter }
However, I'm somehow stuck in defining the do something here
part. I believe you can use reduce method to do it, but it keeps telling me error somehow. Below is how I tried it
val combinedFilter = listOfFilters.reduce { filterA, filterB -> { filterA or filterB } }
infix fun <T> ((T) -> Boolean).or(that: (T) -> Boolean): (T) -> Boolean = { this(it) || that(it) }
But got
Type mismatch.
Required:
Filter
Found:
() → (Int) → Boolean
I believe I did something wrong with the syntax. Hope that you guys can help. Thanks.
That's because you wrapped the expression in an extra lambda, also the type of the accumulator in reduce
wiil be Filter
for your listOfFilters
but or
returns (T) -> Boolean
. You can fix this by specifying the type of accumulator and getting rid of extra lambda:
val combinedFilter = listOfFilters.reduce<(Int) -> Boolean, Filter> { filterA, filterB -> filterA or filterB }
But there is a better way to do it without allocating a lot of lambdas:
val combinedFilter = { x: Int -> listOfFilters.any { filter -> filter(x) } }
val filteredInt = listToBeFiltered.filter(combinedFilter)
or
fun <T> List<(T) -> Boolean>.combineAny() = { x: T -> this.any { filter -> filter(x) } }
val combinedFilter = listOfFilters.combineAny()
val filteredInt = listToBeFiltered.filter(combinedFilter)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.