Let records
be stream/collection and extract
function which transforms data form an element of such collection.
Is there a way in Kotlin to write
records.map {extract(it)}
without explicitely applying(it)
?
E.g. records.map(extract)
or records.map {extract}
A function reference is typically used to pass an expression or set of instructions from one part of your code to another. There are a few other ways to accomplish this in Kotlin.
Since no assignment is possible for function parameters, the main advantage of passing by reference in C++ does not exist in Kotlin.
You can assign them to variables and constants just as you can any other type of value, such as an Int or a String . This function takes two parameters and returns the sum of their values. Here, the name of the variable is function and its type is inferred as (Int, Int) -> Int from the add function you assigned to it.
If extract
is a value (local variable, property, parameter) of a functional type (T) -> R
or T.() -> R
for some T
and R
, then you can pass it directly to map
:
records.map(extract)
Example:
val upperCaseReverse: (String) -> String = { it.toUpperCase().reversed() }
listOf("abc", "xyz").map(upperCaseReverse) // [CBA, ZYX]
If extract
is a top-level single argument function or a local single argument function, you can make a function reference as ::extract
and pass it to map
:
records.map(::extract)
Example:
fun rotate(s: String) = s.drop(1) + s.first()
listOf("abc", "xyz").map(::rotate) // [bca, yzx]
If it is a member or an extension function of a class SomeClass
accepting no arguments or a property of SomeClass
, you can use it as SomeClass::extract
. In this case, records
should contain items of SomeType
, which will be used as a receiver for extract
.
records.map(SomeClass::extract)
Example:
fun Int.rem2() = this % 2
listOf("abc", "defg").map(String::length).map(Int::rem2) // [1, 0]
Since Kotlin 1.1, if extract
is a member or an extension function of a class SomeClass
accepting one argument, you can make a bound callable reference with some receiver foo
:
records.map(foo::extract)
records.map(this::extract) // to call on `this` receiver
Example:
listOf("abc", "xyz").map("prefix"::plus) // [prefixabc, prefixxyz]
(runnable demo with all the code samples above)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With