scala - 使用两个条件过滤列表并创建 map scala

标签 scala functional-programming mapreduce

我有一个保存交易的案例类(假设为资金转账)。为了简单起见,我将使用下面的

case class Trans(from: String, to: String, amount: Int)

我有交易列表

val tl = List(
  Trans("a", "b", 30), 
  Trans("a", "c", 40),
  Trans("b", "c", 10),
  Trans("b", "a", 25),
  Trans("c", "a", 15)
)

我想根据对此列表进行分组。然后需要将组的总和存入Map。 map 将元素保留在下面的结构中

("a" -> (70, 40))
// "a" is the key
// "70" is the sum of values where "a" is 'from' (30 + 40)
// "40" is the sum of values where "a" is 'to' (25 + 15)

例如,关于列表应将输出填充为

Map("a" -> (70, 40), "b" -> (35, 30), "c" -> (15, 50))

我可以使用两个语句进行此过滤,并将它们组合起来,如下所示

// out map
val mOut = tl.map(t => (t.from, t.amount)).groupBy(_._1).map(s => (s._1, s._2.sum))

// in map
val mIn = tl.map(t => (t.to, t.amount)).groupBy(_._1).map(s => (s._1, s._2.sum))

// finally I can join these tow maps to have the final output

有没有办法用单个/一个语句来做到这一点?

最佳答案

如果您是 catsscalaz 用户,您可以使用 foldMap:

import cats._, implicits._ // or...
//import scalaz._, Scalaz._


case class Trans(from: String, to: String, amount: Int)

val tl = List(
  Trans("a", "b", 30), 
  Trans("a", "c", 40),
  Trans("b", "c", 10),
  Trans("b", "a", 25),
  Trans("c", "a", 15)
)

tl foldMap {
    case Trans(from, to, am) => Map(from -> (am, 0), to -> (0, am))
}

关于scala - 使用两个条件过滤列表并创建 map scala,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45792229/

相关文章:

scala - 以编程方式为 WSClient 指定证书

.net - 在.Net中使用Scala有什么好处?

eclipse - 在Eclipse中以本地模式调试MapReduce Hadoop。连接远程虚拟机失败

couchdb - 在 CouchDB 中执行一对多 "JOIN"的最佳方法

scala - $() 在 Scala 中是什么意思?

Actors 的 Scala 消息总线实现?

unit-testing - 如何在函数式编程中编写好的单元测试

hadoop - Amazon Elastic MapReduce 引导操作不工作

haskell - 获取终端宽度 Haskell

javascript - 这个 'run once' Javascript 函数是如何工作的?