Reputation: 9621
I have this code:
val products = List()
def loadProducts(report: (Asset, Party, AssetModel, Location, VendingMachineReading)) = {
report match {
case (asset, party, assetModel, location, reading) =>
EvadtsParser.parseEvadts(reading.evadts, result)
(result.toMap).map(product => ReportData(
customer = party.name,
location = location.description,
asset = asset.`type`,
category = "",
product = product._1,
counter = product._2,
usage = 0,
period = "to be defined")).toList
}
}
results.foreach(result => products ::: loadProducts(result))
println(products)
Can you please tell me what I am doing wrong because products list is empty? If I println products
inside loadProducts
method, products is not empty. Is the concatenation I am doing wrong?
PS: I am a scala beginner.
Upvotes: 0
Views: 148
Reputation: 62835
As I've already said, ::: yields a new list instead of mutating the one you already have in place.
http://take.ms/WDB http://take.ms/WDB
You have two options to go: immutable and mutable
Here is what you can do in immutable and idiomatic style:
def loadProducts(report: (...)): List[...] = {
...
}
val products = result.flatMap(result => loadProducs(result))
println(products)
But also, you can tie with mutability and use ListBuffer to do the things you've wanted:
def loadProducts(report: (...)): List[T] = {
...
}
val buffer = scala.collection.mutable.ListBuffer[T]()
result.foreach(result => buffer ++ = loadProducs(result))
val products = buffer.toList
println(products)
P.S. flatMap( ...)
is an analog to map(...).flatten
, so don't be confused that I and Tomasz written it so differently.
Upvotes: 7
Reputation: 340733
List
type is immutable, val
implies a reference that never changes. Thus you can't really change the contents of products
reference. I suggest building a "list of lists" first and then flattening:
val products = results.map(loadProducts).flatten
println(products)
Notice that map(loadProducts)
is just a shorthand for map(loadProducts(_))
, which is a shorthand for map(result => loadProducts(result))
.
If you become more experienced, try foldLeft()
approach, which continuously builds products
list just like you wanted to do this:
results.foldLeft(List[Int]())((agg, result) => agg ++ loadProducts(result))
Upvotes: 4