我有这段代码:
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初学者。
答案 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))