Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Scala中对整数元组列表排序_Scala_Sorting - Fatal编程技术网

如何在Scala中对整数元组列表排序

如何在Scala中对整数元组列表排序,scala,sorting,Scala,Sorting,给定整数元组列表: List[(Int, Int, Int)] = List((2,1,3), (4,2,6),...) 我想按第三个分量对它们进行排序,但是如果两个元组有相同的第三个分量,那么我想按第二个分量对它们进行排序。例如,我想要(6,3,9)

给定整数元组列表:

List[(Int, Int, Int)] =  List((2,1,3), (4,2,6),...)
我想按第三个分量对它们进行排序,但是如果两个元组有相同的第三个分量,那么我想按第二个分量对它们进行排序。例如,我想要(6,3,9)<(4,7,9)。以下是我尝试过的:

     def order(k: List[(Int, Int, Int)]) = {
        var t = List[Int]()
        if (k.map(_._3) == t) {
            k.sortBy(_._2)
            t = k.map(_._3)
            k
        } else {
            k.sortBy(_._3)
            t = k.map(_._3)
            k
        }   
     }

提前谢谢你

一种相当简单且速度惊人的方法是使用稳定的排序算法,首先按第一个分量排序,然后按第二个分量排序,然后按第三个分量排序。 因为您最后按第三个组件排序,所以这将占主导地位。使用稳定排序时,最后一个组件中绑定的对象将按前一个组件排序:

Sorting.stableSort(k, (x, y) => x._1 < y._1)
Sorting.stableSort(k, (x, y) => x._2 < y._2)
Sorting.stableSort(k, (x, y) => x._3 < y._3)
(假设
Seq.sortBy
不稳定。)

或者(这是更经典、更明显的方法),编写一个比较器(
排序
),如果第三个分量不同,则使用第二个分量,如果第二个分量不同,最后使用第一个分量。这可能不是很“鳞片化”,但它非常干净且易于理解:

val result = intOrdering.compare(x._3, y._3)
if (result == 0) result = intOrdering.compare(x._2, y._2)
if (result == 0) result = intOrdering.compare(x._1, y._1)
result
同样,您也可以使用按键功能(但这需要2倍的内存):


您可以提供自己的
排序[Tuple3[Int,Int,Int]
,然后只需使用
列表上的
排序
。例如,这里类似于
Tuple3
上的标准
排序,只是纵坐标上的排序是反向的。对于任何
(a,b,c)
c
的优先级高于
b
b
的优先级高于
a
。您没有真正提到如何处理
a
,因此如果您不关心它,可以删除相关行

val list = List((2,1,3), (4,2,6), (4,7,9), (6,3,9), (6,7,11), (6,17,19), (8,4,12), (8,14,18), (10,5,15), (12,1,17), (12,6,18))

implicit def t3Ordering(implicit intOrdering: Ordering[Int]) = new Ordering[Tuple3[Int, Int, Int]] {
    def compare(x: (Int, Int, Int), y: (Int, Int, Int)): Int = {
        val compare3 = intOrdering.compare(x._3, y._3)
        if (compare3 != 0) return compare3
        val compare2 = intOrdering.compare(x._2, y._2)
        if (compare2 != 0) return compare2
        val compare1 = intOrdering.compare(x._1, y._1)
        if (compare1 != 0) return compare1
        0
    }
}

scala> list.sorted
res0: List[(Int, Int, Int)] = List((2,1,3), (4,2,6), (6,3,9), (4,7,9), (6,7,11), (8,4,12), (10,5,15), (12,1,17), (12,6,18), (8,14,18), (6,17,19))
或者更一般地根据
Tuple
纵坐标反转排序(对于
Tuple3
):

根据.

看来

k.sortBy(x => (x._3 , x._2))
完成任务并返回

List[(Int, Int, Int)] = List((2,1,3), (4,2,6), (6,3,9), (4,7,9), (6,7,11),
          (8,4,12), (10,5,15), (12,1,17), (12,6,18), (8,14,18), (6,17,19))

这也适用于(12,6,18),(8,14,18)

对于大型列表,提供
排序将比
排序更快,因为这需要对每个元素进行转换。您可能已经知道这一点,但元组有自己的排序--增加_1,增加_2,增加_3——因此,如果您可以选择将元组中字段的顺序更改为(c,b,a),您可以使用普通的old
排序
implicit def t3Ordering[T1, T2, T3](implicit ord1: Ordering[T1], ord2: Ordering[T2], ord3: Ordering[T3]) = 
  new Ordering[Tuple3[T1, T2, T3]] {
    def compare(x: (T1, T2, T3), y: (T1, T2, T3)): Int = {
        val compare3 = ord3.compare(x._3, y._3)
        if (compare3 != 0) return compare3
        val compare2 = ord2.compare(x._2, y._2)
        if (compare2 != 0) return compare2
        val compare1 = ord1.compare(x._1, y._1)
        if (compare1 != 0) return compare1
        0
    }
  }
k.sortBy(x => (x._3 , x._2))
List[(Int, Int, Int)] = List((2,1,3), (4,2,6), (6,3,9), (4,7,9), (6,7,11),
          (8,4,12), (10,5,15), (12,1,17), (12,6,18), (8,14,18), (6,17,19))