我有一个整数元组列表
List[(Int, Int, Int)] = 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))
并且我想通过增加c来对它们进行排序,但是如果有相同c的元组则通过增加b来对它们进行排序。因此,在这种情况下,(4,7,9),(6,3,9)的情况我喜欢(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
}
}
提前谢谢!
答案 0 :(得分:6)
一种相当简单且令人惊讶的快速方法是使用稳定的排序算法,首先按第一个组件排序,然后按第二个组件排序,然后排序第三个组件。 由于您按第三个组件排序,因此这将占主导地位。使用稳定排序时,最后一个组件中绑定的对象将按前一个排序:
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)
或等效(但可能更昂贵,因为它构建了一系列键):
Sorting.stableSort(k, x => x._1)
Sorting.stableSort(k, x => x._2)
Sorting.stableSort(k, x => x._3)
(假设Seq.sortBy
不稳定。)
或者(这是更经典和明显的方法),编写一个比较器(Ordering
)使用第三个组件如果不同,那么第二个如果不同< / em>最后是第一个。这可能不是非常&#34; scalish&#34;,但它是恕我直言,非常干净,可以理解:
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倍的内存):
k.sortBy(x => (x._3, x._2, x._1))
答案 1 :(得分:5)
似乎
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)
答案 2 :(得分:1)
您可以提供自己的Ordering[Tuple3[Int, Int, Int]]
,然后在sorted
上使用List
。例如,此处类似于Ordering
上的标准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
):
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
}
}