使用排序来排序数组,升序和降序
我想通过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))) 我的问题是,在前面的例子中,我可以按第三个和第一个元素升序排序,或者两个元素都降序(使用反向).但是如何按第三个元素升序和第一个元素降序排序. 请在您的回答中考虑以下情况: 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("warn"),GDouble("0.234")))) 模式或内部数组将根据输入文件进行更改(在示例中,它是Double,String,Double,但它可能是Double,Double或其他内容). 我目前所做的是将内部数组更改为Iterable,然后使用Ordering [Iterable [GValue]]进行排序或排序[Iterable [GValue]].reverse.但我想按分开的方向排序(第一列升序,然后降低第二列,然后升至第三列,依此类推) 解决方法
使用
Régis Jean-Gilles’
CompositeOrdering from another question,我们可以编写多个订单.
// 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`) 如果要使用Sorting.quickSort对interval数组进行排序,我们需要对元组进行排序: type Interval = (Long,Array[GValue]) implicit object tupleByArray extends Ordering[Interval] { def compare(a: Interval,b: Interval) = a._3 compare b._3 } 现在,您可以使用Sorting.quickSort对间隔进行排序: implicit val arrOrd = `By Col3-Desc/Col1` Sorting.quickSort(intervals) // Array[(Long,Array[GValue])] = // Array( // (30,GString(alarm),GString(warn),GDouble(0.234))),// (10,GString(error),GDouble(100.234))) // ) 在问题更新之前我留下了答案: 在多个字段上排序有一个great article by 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,People(Alice,40)) val array = Array(people,Array(People("B",People("C",2))) array.foreach(ps => Sorting.quickSort(ps)(PeopleOrdering.`By Name-Rev/Age`)) // > array // Array[Array[People]] = Array( // Array(People(Bob,40)),// Array(People(C,People(B,1)) // ) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |