I can get a correct result when I use my.flatMap {it.toList()}.
I think that the val my is a List<String>, so I needn't to invoke toList(), but the code var ok3=my.flatMap { it } can't be compiled, why?
And more, the code var ok2=my.flatMap { bb } get an error result, why?
Code A
var my=listOf("abc","cef")
var bb=my.toList()
var ok1=my.flatMap {it.toList()}
var ok2=my.flatMap { bb }
//var ok3=my.flatMap { it } //It's wrong
Result

To Naetmul:
Thanks!
Why do you think that it is String type in the code val ok3=my.flatMap { it }
In my mind, it should be my type in the lambda expression, and my is List<String> type.
Image

Sidenote: If you do not re-assign, val is more preferred than var.
val my = listOf("abc","cef")
val bb = my.toList()
Here, the type of my is List<String>, and its elements are "abc" and "cef".
The type of bb is List<String> because List is transformed into List,
and its elements are "abc" and "cef".
i.e., my and bb are equivalent, although they are different instances. You do not need bb.
var ok1 = my.flatMap {it.toList()}
This is similar to
var ok1 = listOf<Char>() // empty List
for (it in my) {
// `it` is the `String` type.
// For the 1st iteration, it = "abc"
// For the 2nd iteration, it = "cef"
val chars: List<Char> = it.toList() // String is transformed into List of Chars
ok1 = ok1 + chars
}
var ok2 = my.flatMap { bb }
This is similar to
var ok2 = listOf<String>() // empty List
for (it in my) {
// `it` is the `String` type.
// For the 1st iteration, it = "abc"
// For the 2nd iteration, it = "cef"
ok2 = ok1 + bb // You know, bb = listOf("abc, "cef")
}
So, ok2 = bb + bb (the for-loop is iterated twice because my has 2 elements.)
which means ok2 = listOf("abc", "cef") + listOf("abc", "cef")
which means ok2 = listOf("abc", "cef", "abc", "cef")
val ok3=my.flatMap { it } //It's wrong
This is similar to
var ok3 = listOf<?>() // empty List
for (it in my) {
// `it` is the `String` type.
// For the 1st iteration, it = "abc"
// For the 2nd iteration, it = "cef"
ok3 = ok3 + it
}
ok3 must be the List type. However, it is String type, the type does not match.
So, compile error!
List of String, you can use joinToString() method.
val my = listOf("abc", "cef")
val concat = my.joinToString("") // insert empty string between elements.
Refer to the Kotlin standard library document of List.
fun <T, R> Iterable<T>.flatMap( transform: (T) -> Iterable<R> ): List<R>Returns a single list of all elements yielded from results of transform function being invoked on each element of original collection.
Assume a variable list has the type List<T>.
If we want to execute val newList = list.flatMap(function), then
function should have the function type (T) -> Iterable<R>.
(function's parameter is T-type, and it retuns Iterable<R>. List is a subtype of Collection, and Collection is a subtype ofIterable, soListis a subtype ofIterable`.)
newList will have the type List<R>.
it in the question will be the parameter of function.
So, it will be T-type, not List<T>-type.
i.e., it will be String-type, not List<String>-type.
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