Scala 中的聚合列表值
从包含名义和货币两个参数的对象列表开始,如何聚合每种货币的名义总金额?
鉴于:
case class Trade(name: String, amount: Int, currency: String)
val trades = List(
Trade("T150310", 10000000, "GBP"),
Trade("T150311", 10000000, "JPY"),
Trade("T150312", 10000000, "USD"),
Trade("T150313", 100, "JPY"),
Trade("T150314", 1000, "GBP"),
Trade("T150315", 10000, "USD")
)
我怎样才能得到:
Map(JPY -> 10000100, USD -> 10010000, GBP -> 10001000)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我编写了一个简单的分组操作(实际上是一个从
Iterable
进行隐式转换的Groupable
trait
),它允许您对交易进行分组按其货币
:因此
Groupable
只是提供了一种从Iterable
中的每个项目中提取键的方法,并且然后将具有相同密钥的所有此类项目分组。 因此,在您的情况下:您现在可以做一个非常简单的
mapElements
(mm
是一个Map
)和一个foldLeft
> (或/:
- 非常值得理解foldLeft
运算符,因为它可以对集合进行极其简洁的聚合)以获得总和:如果我在这方面犯了一些错误,请道歉最后一行。
ts
是mm
的值,(当然)是Iterable[Trade]
。I wrote a simple group-by operation (actually a
Groupable
trait
with an implicit conversion from anIterable
) which would allow you to group your trades by theircurrency
:So
Groupable
is simply providing a way to extract a key from each item in anIterable
and then grouping all such items which have the same key. So, in your case:You can now do a quite simple
mapElements
(mm
is aMap
) and afoldLeft
(or/:
- well worth understanding thefoldLeft
operator as it enables extremely concise aggregations over collections) to get the sum:Apologies if I've made some mistakes in that last line.
ts
are the values ofmm
, which are (of course)Iterable[Trade]
.从 Scala 2.13 开始,大多数集合都提供了 groupMapReduce 方法(顾名思义)与
groupBy
等效(更高效),后跟mapValues
和一个归约步骤:这是:
group
s 元素基于其货币(groupMapReduce 的组部分)map
将分组值映射到其金额(组MapReduce 的映射部分)减少
的值(_ + _
)通过对它们求和(减少 groupMapReduce 的一部分)。这是等效版本 通过以下列表一次性执行:
Starting
Scala 2.13
, most collections are provided with the groupMapReduce method which is (as its name suggests) an equivalent (more efficient) of agroupBy
followed bymapValues
and a reduce step:This:
group
s elements based on their currency (group part of groupMapReduce)map
s grouped values to their amount (map part of groupMapReduce)reduce
s values (_ + _
) by summing them (reduce part of groupMapReduce).This is an equivalent version performed in one pass through the List of:
如果你使用后备箱,机器已经在那里了。 groupBy 是在 Traversable 上定义的,并且 sum 可以直接应用于列表,您不必编写折叠。
If you use trunk the machinery is already there. groupBy is defined on Traversable and sum can be applied directly to the list, you don't have to write a fold.