更新Map的值

时间:2013-02-02 11:40:19

标签: scala

我有一张地图:

Map("product1" -> List(Product1ObjectTypes), "product2" -> List(Product2ObjectTypes))

其中ProductObjectType有一个字段usage。根据其他字段(counter),我必须更新所有ProductXObjectTypes

问题是此更新取决于之前的 ProductObjectType,在迭代此地图的mapValues时,我无法找到获取上一项的方法。所以基本上,要更新我需要的当前usageCurrentProduct1ObjectType.counter - PreviousProduct1ObjectType.counter

有没有办法做到这一点?

我开始就像:

val reportsWithCalculatedUsage =
  reportsRefined.flatten.flatten.toList.groupBy(_._2.product).mapValues(f)

但我不知道mapValues如何访问上一个列表项。

2 个答案:

答案 0 :(得分:2)

请注意,常规地图是无序集合,您需要使用类似TreeMap的内容来获得可预测的迭代顺序。

无论如何,根据我的理解,你想要在地图中获得所有值的对。尝试这样的事情:

scala> val map = Map(1 -> 2, 2 -> 3, 3 -> 4)
scala> (map, map.tail).zipped.foreach((t1, t2) => println(t1 + " " + t2))
(1,2) (2,3)
(2,3) (3,4)

答案 1 :(得分:2)

我不确定我是否完全理解,但如果您想根据其前辈更新列表中的值,通常可以通过折叠来完成:

case class Thing(product: String, usage: Int, counter: Int)

val m = Map(
  "product1" -> List(Thing("Fnord", 10, 3), Thing("Meep", 0, 5))
  //... more mappings
)

//> Map(product1 -> List(Thing(Fnord,10,3), Thing(Meep,0,5)))

m mapValues { list => list.foldLeft(List[Thing]()){
  case (Nil, head) =>
    List(head)
  case (tail, head) =>
    val previous = tail.head
    val current = head copy (usage = head.usage + head.counter - previous.counter)
    current :: tail
} reverse }

//> Map(product1 -> List(Thing(Fnord,10,3), Thing(Meep,2,5)))