当前位置: 首页 > 知识库问答 >
问题:

使用排序对数组进行升序和降序排序

慕金林
2023-03-14

我想按第三个和第一个元素对元组数组进行排序,因此我使用了以下代码:

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)))

我的问题是,在前面的例子中,我可以按第三个元素和第一个元素的升序排序,也可以按它们的降序排序(使用反向)。但是如何按第三个元素的升序和第一个元素的降序排序。

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

Array[Array[People]]  

在这种情况下,我不知道内部数组的确切大小(取决于我读入该数组的文件模式),我想按侧中的所有项进行排序(一些升序和一些降序)。

编辑:看起来,我明白了。

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

  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

我想做一个这样的代码。

// (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"))))

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

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

共有2个答案

於永寿
2023-03-14

对于要排序Strings desceding的示例,请在排序之前添加此项

  implicit object ReverseStringOrdering extends Ordering[String] {
    def compare(x: String, y: String) = -1 * x.compareTo(y)
  }

所以,一般来说,只需添加隐式排序对象,该对象的类型是要使用重写的比较方法进行降序排序的。此解决方案仅在按不同类型排序时有效。

如果要按第一项升序和第二项降序排序,请在排序前添加以下内容:

 implicit def AscFirstDescSecondTuple2[T1, T2](implicit ord1: Ordering[T1], ord2: Ordering[T2]): Ordering[(T1, T2)] =
    new Ordering[(T1, T2)]{
      def compare(x: (T1, T2), y: (T1, T2)): Int = {
        val compare1 = ord1.compare(x._1, y._1)
        if (compare1 != 0) return compare1
        val compare2 = -1 * ord2.compare(x._2, y._2)
        if (compare2 != 0) return compare2
        0
      }
    } 
拓拔欣嘉
2023-03-14

使用来自另一个问题的Régis Jean Gilles的组合订单,我们可以组合多个订单

// Ordering to sort an Array[GValue] by column "col"
def orderByColumn(col: Int) = Ordering.by { ar: Array[GValue] => ar(col - 1) }

val `By Col3-Desc/Col1` = 
  CompositeOrdering(orderByColumn(3).reverse, orderByColumn(1))

val `By Col1/Col2/Col3` = 
  CompositeOrdering(orderByColumn(1), orderByColumn(2), orderByColumn(3))

现在,我们可以排序类型Array[GValue]的数组,并且可以使用sortBy排序间隔

intervals.sortBy(_._3)(`By Col3-Desc/Col1`)

如果要使用排序对间隔数组进行排序。快速排序,我们需要对元组进行排序:

type Interval = (Long, Long, Array[GValue])
implicit object tupleByArray extends Ordering[Interval] {
  def compare(a: Interval, b: Interval) = a._3 compare b._3
}

现在,您可以使用排序对间隔进行排序。快速排序

implicit val arrOrd = `By Col3-Desc/Col1`
Sorting.quickSort(intervals)

// Array[(Long, Long, Array[GValue])] = 
// Array(
//  (30,2000,Array(GDouble(-10.2), GString(alarm), GString(warn),  GDouble(0.234))), 
//  (10,20,Array(GDouble(10.2), GString(alarm), GString(error), GDouble(100.234)))
// )

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

Eric Loots有一篇关于多字段排序的伟大文章。

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

case class People(name: String, age: Int)

object PeopleOrdering {
  // sort by name descending and age ascending
  implicit object `By Name-Rev/Age` extends Ordering[People] {
    def compare(a: People, b: People): Int = {
      import scala.math.Ordered._
      implicit val ord = Ordering.Tuple2[String, Int]
      (b.name, a.age) compare (a.name, b.age)
    }
  }
}

val people = Array(People("Alice", 40), People("Bob", 50), People("Charlie", 20))
Sorting.quickSort(people)(PeopleOrdering.`By Name-Rev/Age`)
// > people
// Array[People] = Array(People(Bob,20), People(Bob,50), People(Alice,40))

val array = Array(people, Array(People("B", 1), People("C", 2)))
array.foreach(ps => Sorting.quickSort(ps)(PeopleOrdering.`By Name-Rev/Age`))
// > array
// Array[Array[People]] = Array(
//   Array(People(Bob,20), People(Bob,50), People(Alice,40)), 
//   Array(People(C,2), People(B,1))
// )

 类似资料:
  • 我正在尝试对我的数组进行升序和降序排序。不过,我似乎不知道如何正确地执行此操作。我尝试了不同的方法,但都不起作用。当我单击两个按钮时,应该会发生这种情况,一个ID为“stigande”升序,一个ID为“ 爪哇语

  • 有人能提供帮助,如何检查排序降序数组以及?干杯!

  • 我有数据。表中有大约300万行和40列。我希望在组内按降序对该表排序,如以下sql模拟代码: 数据中是否存在等效的方法。这张桌子可以吗?到目前为止,我必须将其分解为两个步骤: 这非常快,只需要几秒钟。 这一步需要更长的时间(5分钟)。 更新:有人评论要执行<code>X 我的方法是:setkey()然后是order(-Month) 我现在的问题是:如果我想按年、MemberId和一个又一个排序(年

  • 我注意到一件非常奇怪的事情。 读完这节课后,我在C中实现了一些堆排序代码。 代码如下。 奇怪的是,对我来说,构建min堆-提取min(或在构建min堆后在根目录下执行min-heapify)应该按升序进行。然而,在执行此代码并打印出结果向量后,我得到: 在试图弄清楚发生了什么的时候,我改变了 到 最终选择较大(或最大)的父节点和子节点,得到的向量为: 我是否做错了什么,或者我对堆/堆排序的理解不清

  • 我有98000个美国家庭街道地址,我需要按照“步行”的顺序进行排序,也就是说,按照你要走的顺序,沿着街道的一侧走,然后穿过街道往回走。 所需的df结果,对奇数街道编号进行升序排序,然后对偶数街道编号切换到降序排序。[抱歉,第一个问题,还没有资格复制Jupyter笔记本的图像] 4列:数字、街道、城镇、偶数 “编号”列的预期结果:1231 1233 1235 1237 1239 1238 1236

  • 问题内容: 令我惊讶的是,以前没有提出过这个具体问题,但我的确没有在SO或文档中找到它。 假设我有一个包含整数的随机numpy数组,例如: 如果对它进行排序,则默认情况下我将获得升序: 但我希望解决方案按 降序 排序。 现在,我知道我可以永远做: 但这最后的陈述 有效 吗?它不是按升序创建副本,然后反转此副本以反转顺序获得结果吗?如果确实如此,是否有有效的选择?看起来好像不接受参数来更改排序操作中