简体   繁体   English

通过分组减少/折叠scala序列

[英]Reduce/fold over scala sequence with grouping

In scala, given an Iterable of pairs, say Iterable[(String, Int]) , is there a way to accumulate or fold over the ._2 s based on the ._1 s? 在Scala中,给定一个Iterable对,例如Iterable[(String, Int]) ,是否有一种方法可以基于._2 s累积或折叠._1 s? Like in the following, add up all the #s that come after A and separately the # after B 如下所示,将A之后的所有#和B之后的#分别相加

List(("A", 2), ("B", 1), ("A", 3))

I could do this in 2 steps with groupBy 我可以使用groupBy分两步完成此操作

val mapBy1 = list.groupBy( _._1 )
for ((key,sublist) <- mapBy1) yield (key, sublist.foldLeft(0) (_+_._2))

but then I would be allocating the sublists, which I would rather avoid. 但是那样的话我会分配子列表,而我宁愿避免。

You could do something like: 您可以执行以下操作:

list.foldLeft(Map[String, Int]()) {
   case (map, (k,v)) => map + (k -> (map.getOrElse(k, 0) + v))
}

You could build the Map as you go and convert it back to a List after the fact. 您可以随时构建Map ,然后将其转换回List

listOfPairs.foldLeft(Map[String,Int]().withDefaultValue(0)){
      case (m,(k,v)) => m + (k -> (v + m(k)))
    }.toList

You could also use groupBy with mapValues : 您还可以将groupBymapValues groupBy使用:

list.groupBy(_._1).mapValues(_.map(_._2).sum).toList
res1: List[(String, Int)] = List((A,5), (B,1))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM