使用排序来排序数组,升序和降序

Abd*_*man 5 arrays sorting scala

我想通过3rd和first元素对元组数组进行排序,因此我使用了以下代码:

import scala.util.Sorting
val pairs = Array(("a", 5, 2), ("c", 3, 1), ("b", 1, 3))

// sort by the 3rd element, then 1st
Sorting.quickSort(pairs)(Ordering[(Int, String)].on(x => (x._3, x._1)))
Run Code Online (Sandbox Code Playgroud)

我的问题是,在前面的例子中,我可以按第三个和第一个元素升序排序,或者两个元素都降序(使用反向).但是如何按第三个元素升序和第一个元素降序排序.

请在您的回答中考虑以下情况:

Array[Array[People]]  
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我不知道内部数组的确切大小(取决于我读入此数组的文件架构),我想按侧面的所有项目排序(一些升序和一些降序).

编辑:看起来,我很想念.

这是我的完整案例:我有以下课程:

  sealed trait GValue extends Serializable with Ordered[GValue]{
def compare(o: GValue): Int = {
  o match {
    case GDouble(v) => this.asInstanceOf[GDouble].v compare v
    case GString(v) => this.asInstanceOf[GString].v compare v
  }
}

case class GDouble(v: Double) extends GValue

case class GString(v: String) extends GValue
Run Code Online (Sandbox Code Playgroud)

我想做一个像这样的代码.

// (startInterval, StopInterval, ArrayOfColumns)
    val intervals: Array[(Long,Long,Array[GValue])] =
Array((10,20,Array(GDouble(10.2), GString("alarm"), GString("error"),GDouble("100.234"))),
    (30,2000,Array(GDouble(-10.2), GString("alarm"), GString("warn"),GDouble("0.234"))))
Run Code Online (Sandbox Code Playgroud)

模式或内部数组将根据输入文件进行更改(在示例中,它是Double,String,String,Double,但它可能是Double,Double或其他内容).我想找到一种方法来排序,覆盖内部数组的所有情况(关于类型和长度),升序和降序.

我目前所做的是将内部数组更改为Iterable,然后使用Ordering [Iterable [GValue]]进行排序或排序[Iterable [GValue]].reverse.但我想按分开的方向排序(第一列升序,然后降低第二列,然后升至第三列,依此类推)

Pet*_*ens 3

使用另一个问题中的R\xc3\xa9gis Jean-Gilles\'CompositeOrdering,我们可以组合多个Orderings.

\n\n
// Ordering to sort an Array[GValue] by column "col"\ndef orderByColumn(col: Int) = Ordering.by { ar: Array[GValue] => ar(col - 1) }\n\nval `By Col3-Desc/Col1` = \n  CompositeOrdering(orderByColumn(3).reverse, orderByColumn(1))\n\nval `By Col1/Col2/Col3` = \n  CompositeOrdering(orderByColumn(1), orderByColumn(2), orderByColumn(3))\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在我们可以对 type 的数组进行排序Array[GValue],您可以intervals使用以下方法对您的数组进行排序sortBy

\n\n
intervals.sortBy(_._3)(`By Col3-Desc/Col1`)\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果你想用 来intervals对数组进行排序Sorting.quickSort,我们需要一个元Ordering组:

\n\n
type Interval = (Long, Long, Array[GValue])\nimplicit object tupleByArray extends Ordering[Interval] {\n  def compare(a: Interval, b: Interval) = a._3 compare b._3\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在您可以intervals使用以下命令对您进行排序Sorting.quickSort

\n\n
implicit val arrOrd = `By Col3-Desc/Col1`\nSorting.quickSort(intervals)\n\n// Array[(Long, Long, Array[GValue])] = \n// Array(\n//  (30,2000,Array(GDouble(-10.2), GString(alarm), GString(warn),  GDouble(0.234))), \n//  (10,20,Array(GDouble(10.2), GString(alarm), GString(error), GDouble(100.234)))\n// )\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

我留下问题更新之前的答案:

\n\n

Eric Loots有一篇关于多个字段排序的精彩文章。

\n\n

在你的情况下,Array[People]这可能看起来像:

\n\n
case class People(name: String, age: Int)\n\nobject PeopleOrdering {\n  // sort by name descending and age ascending\n  implicit object `By Name-Rev/Age` extends Ordering[People] {\n    def compare(a: People, b: People): Int = {\n      import scala.math.Ordered._\n      implicit val ord = Ordering.Tuple2[String, Int]\n      (b.name, a.age) compare (a.name, b.age)\n    }\n  }\n}\n\nval people = Array(People("Alice", 40), People("Bob", 50), People("Charlie", 20))\nSorting.quickSort(people)(PeopleOrdering.`By Name-Rev/Age`)\n// > people\n// Array[People] = Array(People(Bob,20), People(Bob,50), People(Alice,40))\n\nval array = Array(people, Array(People("B", 1), People("C", 2)))\narray.foreach(ps => Sorting.quickSort(ps)(PeopleOrdering.`By Name-Rev/Age`))\n// > array\n// Array[Array[People]] = Array(\n//   Array(People(Bob,20), People(Bob,50), People(Alice,40)), \n//   Array(People(C,2), People(B,1))\n// )\n
Run Code Online (Sandbox Code Playgroud)\n