Reputation: 523
I'm using a range with an inline transform so that I can have a list of values and that I want to send it to a method in forEach. But, somehow I see that is not happening. This is the example code I'm using
var valuesList: List<Test> = mutableListOf()
(1..5).map {
valuesList.plus(Test(<curr value>, Instant.now())
// Have a condition to check the value and using the value in next statement
valuesList.plus(Test(<prev value>, Instant.now())
}.forEach { <expecting a list here to send to a method> }
Somehow I always see valuesList as empty list. Can anyone let me know the mistake I'm doing.
Thanks in advance.
Upvotes: 0
Views: 759
Reputation: 2629
You can't add items to List
, try to change it to MutableList
, also you need to use .add()
to add items to the list not .plus()
, .plus()
is going to return a new list not adding items to the old one.
so your code should look like this :
val valuesList: MutableList<Test> = mutableListOf()
(1..5).map {
valuesList.add(Test(<curr value>, Instant.now())
// Have a condition to check the value and using the value in next statement
valuesList.add(Test(<prev value>, Instant.now())
}.forEach { <expecting a list here to send to a method> }
Also forEach
here is not going to receive valuesList
so if you wan to iterate valuesList
, iterate it separately after the map :
valuesList.forEach { }
Upvotes: 2
Reputation: 7109
You've created a mutable list, but assigned it to an immutable list. Change List<Test>
to MutableList<Test>
var valuesList: MutableList<String> = mutableListOf()
You should probably also make it a val
, not a var
. You want to change the contents of the list, not the variable that points to the list.
val valuesList: MutableList<String> = mutableListOf()
plus()
is an operator function that combines two lists, and returns the result. It does NOT change the lists that are being provided.
.map {
// this `plus` returns a new list
valuesList.plus(Test(<curr value>, Instant.now())
// Have a condition to check the value and using the value in next statement
valuesList.plus(Test(<prev value>, Instant.now())
}
plusAssign()
is the one you want - it appends the values of the second list onto the first
valuesList.plusAssign("<current>")
Because plusAssign()
is an operator function, it means we can use +=
to make it clear. Then we can work with lists just like how we would work with integers.
// the string will be appended to the end of the list
valuesList += "<current>"
See more: Kotlin docs on plus and minus operators
It looks unusual that you're 'mapping' 1 to 5, but not using the integer, and additionally looping over the result.
Without further details I can't say much (please update your question with more code if you want more information). But from what you've shown I think you can use an initializer function to build an immutable list in one go:
// create a size-5 list, with elements e1, e2, e3, e4, e5
val valuesList: List<String> = List(5) { i ->
"e$i"
}
I can also recommend the collection builder functions.
Upvotes: 2
Reputation: 7163
I would recommend to construct valuesList in one go. Something along this (not knowing more about the condition):
import java.time.Instant
data class Test(val value: Any, val now: Instant)
val valuesList: List<Test> = (1..5)
.flatMap { i ->
val value1 = Test(i, Instant.now())
val condition = true // calculate the condition to true or false here
val value2 = if (condition) Test(i, Instant.now()) else null
listOfNotNull(value1, value2)
}
valuesList.forEach(::println)
Upvotes: 2