为什么我的清单是空的?

时间:2013-01-30 19:45:49

标签: scala

我有这段代码:

    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)

你能告诉我我做错了什么因为产品清单是空的吗?如果我在products方法中打印loadProducts,则产品不为空。连接我做错了吗?

PS:我是scala初学者。

2 个答案:

答案 0 :(得分:7)

正如我已经说过的那样,:::会产生一个新的列表而不是改变你已经存在的列表。

http://take.ms/WDB http://take.ms/WDB

你有两个选择:不可变和可变

以下是您在不可变和惯用风格中可以做的事情:

def loadProducts(report: (...)): List[...] = {
  ...
}

val products = result.flatMap(result => loadProducs(result))
println(products)

但是,你可以配合可变性并使用ListBuffer来做你想要的事情:

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( ...)map(...).flatten类似,所以不要混淆我和Tomasz写的不同。

答案 1 :(得分:4)

List类型是不可变的,val表示永远不会更改的引用。因此,您无法真正更改products引用的内容。我建议先建立一个“清单列表”,然后展平:

val products = results.map(loadProducts).flatten
println(products)

请注意,map(loadProducts)只是map(loadProducts(_))的简写,是map(result => loadProducts(result))的简写。

如果您变得更有经验,请尝试foldLeft()方法,这样就可以像您想要的那样持续构建products列表:

results.foldLeft(List[Int]())((agg, result) => agg ++ loadProducts(result))