Cristian Boariu
Cristian Boariu

Reputation: 9621

Why my list is empty?

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

Answers (2)

om-nom-nom
om-nom-nom

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

Tomasz Nurkiewicz
Tomasz Nurkiewicz

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

Related Questions