[英]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.