我正在使用scala来实现算法。我有一个案例需要实现这样的场景:
test = Map(t -> List((t,2)), B -> List((B,3), (B,1)), D -> List((D,1)))
我需要一些每个常见元组的第二个成员。
期望的结果:
Map((t,2),(B,4),(D,1))
val resReduce = test.foldLeft(Map.empty[String, List[Map.empty[String, Int]]){(count, tup) => count + (tup -> (count.getOrElse(tup, 0) + 1))
我正在尝试使用“减少”,我必须经历我所做的每一个小组并总结他们的第二个成员。不知道怎么做。
答案 0 :(得分:3)
如果您知道所有列表都是非空的并且以相同的键开头(例如它们是由groupBy
生成的),那么您可以
test.mapValues(_.map(_._2).sum).toMap
或者,您可能需要一个允许您执行错误检查的中间步骤:
test.map{ case(k,xs) =>
val v = {
if (xs.exists(_._1 != k)) ??? // Handle key-mismatch case
else xs.reduceOption((l,r) => l.copy(_2 = l._2 + r._2))
}
v.getOrElse(??? /* Handle empty-list case */)
}
答案 1 :(得分:1)
你可以这样做:
test collect{
case (key, many) => (key, many.map(_._2).sum)
}
其中您不必假设该列表包含任何成员。但是,如果要排除空列表,请添加一个警卫
case (key, many) if many.nonEmpty =>
像那样。
答案 2 :(得分:0)
scala> val test = Map("t" -> List(("t",2)), "B" -> List(("B",3), ("B",1)), "D" -> List(("D",1)))
test: scala.collection.immutable.Map[String,List[(String, Int)]] = Map(t -> List((t,2)), B -> List((B,3), (B,1)), D -> List((D,1)))
scala> test.map{case (k,v) => (k, v.map(t => t._2).sum)}
res32: scala.collection.immutable.Map[String,Int] = Map(t -> 2, B -> 4, D -> 1)
答案 3 :(得分:0)
另一种方法,实质上与已经提出的方法非常相似,
implicit class mapAcc(val m: Map[String,List[(String,Int)]]) extends AnyVal {
def mapCount() = for ( (k,v) <- m ) yield { (k,v.map {_._2}.sum) }
}
然后是给定的
val test = Map("t" -> List(("t",2)), "B" -> List(("B",3), ("B",1)), "D" -> List(("D",1)))
致电
test.mapCount()
递送
Map(t -> 2, B -> 4, D -> 1)