简体   繁体   English

提升algebird聚合器消耗(并返回)地图

[英]Lift algebird aggregator to consume (and return) Map

The example in the README is very elegant: 自述文件中的示例非常优雅:

scala> Map(1 -> Max(2)) + Map(1 -> Max(3)) + Map(2 -> Max(4))
res0: Map[Int,Max[Int]] = Map(2 -> Max(4), 1 -> Max(3))

Essentially the use of Map here is equivalent to SQL's group by . 本质上,此处Map的使用等效于SQL的group by

But how do I do the same with an arbitrary Aggregator? 但是,如何对任意聚合器执行相同操作? For example, to achieve the same thing as the code above (but without the Max wrapper class): 例如,要实现与上面的代码相同的功能(但没有Max包装器类):

scala> import com.twitter.algebird._
scala> val mx = Aggregator.max[Int]
mx: Aggregator[Int,Int,Int] = MaxAggregator(scala.math.Ordering$Int$@78c77)
scala> val mxOfMap = // what goes here?
mxOfMap: Aggregator[Map[Int,Int],Map[Int,Int],Map[Int,Int]] = ...
scala> mxOfMap.reduce(List(Map(1 -> 2), Map(1 -> 3), Map(2 -> 4)))
res0: Map[Int,Int] = Map(2 -> 4, 1 -> 3)

In other words, how to I convert (or "lift") an Aggregator that operates on values of type T into an Aggregator that operates on values of type Map[K,T] (for some arbitrary K )? 换句话说,如何将对T类型的值进行操作的聚合器转换(或“提升”)到对Map[K,T]类型的值进行操作的聚合器(对于任意K )?

Looks like this can be done fairly easily for Semigroup at least. 看起来至少可以对Semigroup相当轻松地完成此操作。 This should be sufficient in the case where there is no additional logic in the "compose" or "present" phases of the aggregator which needs to be preserved (a Semigroup can be obtained from an Aggregator , discarding compose/prepare). 这应该是充足的情况下在有处于“组成”或“存在”需要被保留了聚合器的相位没有额外的逻辑(一个Semigroup可以从能够得到Aggregator时,丢弃撰写/准备)。

The code to answer the original question is: 回答原始问题的代码是:

scala> val sgOfMap = Semigroup.mapSemigroup[Int,Int](mx.semigroup)
scala> val mxOfMap = Aggregator.fromSemigroup(sgOfMap)
scala> mxOfMap.reduce(List(Map(1 -> 2), Map(1 -> 3), Map(2 -> 4)))
res0: Map[Int,Int] = Map(2 -> 4, 1 -> 3)

But in practice, it would be better to start by constructing the arbitrary Semigroup directly, rather than constructing an Aggregator merely to extract the semigroup from: 但是在实践中,最好直接构建任意的Semigroup ,而不是构造仅从以下其中一个提取Semigroup的Aggregator

scala> import com.twitter.algebird._
scala> val mx = Semigroup.from { (x: Int, y: Int) => Math.max(x, y) }
scala> val mxOfMap = Semigroup.mapSemigroup[Int,Int](mx)
scala> mxOfMap.sumOption(List(Map(1 -> 2), Map(1 -> 3), Map(2 -> 4)))
res33: Option[Map[Int,Int]] = Some(Map(2 -> 4, 1 -> 3))

Alternatively, convert to aggregator: Aggregator.fromSemigroup(mxOfMap) 或者,转换为聚合器: Aggregator.fromSemigroup(mxOfMap)

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

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