scala 如何对元组排序? [英] How scala orders tuples?

查看:48
本文介绍了scala 如何对元组排序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试了解 Scala 如何处理元组的排序和排序

I'm trying to understand how scala handles ordering and sorting of tuples

例如,如果我得到了列表

For example, if I got the list

val l = for {i <- 1 to 5} yield (-i,i*2)
Vector((-1,2), (-2,4), (-3,6), (-4,8), (-5,10))

scala 知道如何排序:

scala knows how to sort it:

l.sorted
Vector((-5,10), (-4,8), (-3,6), (-2,4), (-1,2))

但是元组没有<"方法:

But tuple don't have a '<' method:

l.sortWith(_ < _)

error: value < is not a member of (Int, Int)
l.sortWith(_ < _)

scala 如何知道如何对这些元组进行排序?

How does scala know how to sort those tuples?

推荐答案

因为 sorted 有一个隐式参数 ord:

Because sorted have an implicit parameter ord:

def sorted[B>: A](implicit ord: math.Ordering[B]): List[A] Sorts这个顺序按照一个 Ordering.

def sorted[B >: A](implicit ord: math.Ordering[B]): List[A] Sorts this sequence according to an Ordering.

排序稳定.也就是说,相等的元素(由lt) 在排序序列中的出现顺序与原创.

The sort is stable. That is, elements that are equal (as determined by lt) appear in the same order in the sorted sequence as in the original.

ord 用于比较元素的顺序.

ord the ordering to be used to compare elements.

并且在 scala.math.Ordering 中定义了一个隐式转换:

and there is an implicit conversion defined in scala.math.Ordering:

implicit def Tuple2[T1, T2](implicit ord1: Ordering[T1], 
                                     ord2: Ordering[T2]): Ordering[(T1, T2)]

所以 l.sorted 将被转换为 l.sorted(scala.math.Ordering.Tuple2[Int, Int]()).

So l.sorted will be transformed to l.sorted(scala.math.Ordering.Tuple2[Int, Int]()).

测试一下:

scala> def catchOrd[A](xs: A)(implicit ord: math.Ordering[A]) = ord
catchOrd: [A](xs: A)(implicit ord: scala.math.Ordering[A])scala.math.Ordering[A]

scala> catchOrd((1,2))
res1: scala.math.Ordering[(Int, Int)] = scala.math.Ordering$$anon$11@11bbdc80

当然,您可以定义自己的Ordering:

And of course, you can defined your own Ordering:

scala> implicit object IntTupleOrd extends math.Ordering[(Int, Int)] {
     |   def compare(x: (Int, Int), y: (Int, Int)): Int = {
     |     println(s"Hi, I am here with x: $x, y: $y")
     |     val a = x._1*x._2
     |     val b = y._1*y._2
     |     if(a > b) 1 else if(a < b) -1 else 0
     |   }
     | }
defined object IntTupleOrd

scala> Seq((1, 10), (3, 4),  (2, 3)).sorted
Hi, I am here with x: (1,10), y: (3,4)
Hi, I am here with x: (3,4), y: (2,3)
Hi, I am here with x: (1,10), y: (2,3)
res2: Seq[(Int, Int)] = List((2,3), (1,10), (3,4))

EDIT 有一个简短的方法可以让 Tuple[Int, Int] 支持以下所有方法:<, <=, >, >=.

EDIT There is a short way to make Tuple[Int, Int] support all the following methods: <, <=, >, >=.

scala> implicit def mkOps[A](x: A)(implicit ord: math.Ordering[A]): ord.Ops =
     |   ord.mkOrderingOps(x)
mkOps: [A](x: A)(implicit ord: scala.math.Ordering[A])ord.Ops

scala> (1, 2) < (3, 4)
res0: Boolean = true

scala> (1, 2) <= (3, 4)
res1: Boolean = true

scala> (1, 2, 3) <= (1, 2, 4)
res2: Boolean = true

scala> (3, 3, 3, 3) >= (3, 3, 3, 4)
res3: Boolean = false

这篇关于scala 如何对元组排序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆