如何在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))