Scala函数使用泛型函数的映射对Seq进行排序

时间:2012-11-25 21:52:42

标签: scala sorting mapping

我正在尝试编写一个函数,用函数F映射序列S(我称之为F(S)),用S将结果值(F(S))拉开,并按结果排序F(S),返回排序的压缩值(我希望代码清除它,很难放入文本)

这是我目前的代码:

def sortByAndReturnZippedMetric[S,M<:Ordering[AnyVal]]( s:Seq[S], mapper:S=>M):Seq[(M,S)] =
s.map(mapper).zip(s).sortBy(_._1)
然而,Scalac抱怨道:

error: diverging implicit expansion for type scala.math.Ordering[M]
starting with method comparatorToOrdering in trait LowPriorityOrderingImplicits
s.map(mapper).zip(s).sortBy(_._1)

                               ^

我很欣赏可能出现问题的一些指示......

1 个答案:

答案 0 :(得分:6)

Orderingtype class,这意味着如果您想捕获A以特定方式排序的事实,您只需放置{{1}的隐式实例进入范围 - 您没有Ordering[A]延伸A(或Ordering[A]等)。

这种方法的优点是您可以处理特定类型的多个排序(尽管一种类型的一次只能有一个隐式排序)。例如,我可以写下以下内容:

Ordering[AnyVal]

这里使用整数的隐式排序(scala> List(5, 2, 3, 1, 4).sorted res0: List[Int] = List(1, 2, 3, 4, 5) )作为Ordering.Int的隐式参数,但我们也可以显式传递不同的sorted。例如,我们可以通过反转隐含的顺序来创建新的排序:

Ordering

在你的情况下,scala> List(5, 2, 3, 1, 4).sorted(Ordering.Int.reverse) res1: List[Int] = List(5, 4, 3, 2, 1) 正在寻找一个不存在的sortBy。您可以使用context bound轻松解决此问题,以表明您需要Ordering[Ordering[AnyVal]]订购,而不是M延长M

Ordering[AnyVal]

或者你可以跳过语法糖并使用隐含参数:

def sortByZipped[S, M: Ordering](s: Seq[S], mapper: S => M): Seq[(M, S)] =
  s.map(mapper).zip(s).sortBy(_._1)

这与具有上下文绑定的版本完全相同。