Scala排序

排序方法在實際的應用場景中非常常見,Scala裏面有三種排序方法,分別是: sorted,sortBy ,sortWith

分別介紹下他們的功能:

(1)sorted

對一個集合進行自然排序,通過傳遞隱式的Ordering

(2)sortBy

對一個屬性或多個屬性進行排序,通過它的類型。

(3)sortWith

基於函數的排序,通過一個comparator函數,實現自定義排序的邏輯。

例子一:基於單集合單字段的排序

val xs=Seq(1,5,3,4,6,2)
    println("==============sorted排序=================")
   println(xs.sorted) //升序
   println(xs.sorted.reverse) //降序
    println("==============sortBy排序=================")
   println( xs.sortBy(d=>d) ) //升序
   println( xs.sortBy(d=>d).reverse ) //降序
    println("==============sortWith排序=================")
   println( xs.sortWith(_<_) )//升序
   println( xs.sortWith(_>_) )//降序
結果:

==============sorted排序=================
List(1, 2, 3, 4, 5, 6)
List(6, 5, 4, 3, 2, 1)
==============sortBy排序=================
List(1, 2, 3, 4, 5, 6)
List(6, 5, 4, 3, 2, 1)
==============sortWith排序=================
List(1, 2, 3, 4, 5, 6)
List(6, 5, 4, 3, 2, 1)
例子二:基於元組多字段的排序

注意多字段的排序,使用sorted比較麻煩,這裏給出使用sortBy和sortWith的例子

先看基於sortBy的實現:

val pairs = Array(
                      ("a", 5, 1),
                      ("c", 3, 1),
                      ("b", 1, 3)
                       )
 
   //按第三個字段升序,第一個字段降序,注意,排序的字段必須和後面的tuple對應
   val bx= pairs.
   sortBy(r => (r._3, r._1))( Ordering.Tuple2(Ordering.Int, Ordering.String.reverse) )
    //打印結果        
    bx.map( println )
結果:

(c,3,1)
(a,5,1)
(b,1,3)
再看基於sortWith的實現:

val pairs = Array(
                      ("a", 5, 1),
                      ("c", 3, 1),
                      ("b", 1, 3)
                       )
       val b= pairs.sortWith{
      case (a,b)=>{
        if(a._3==b._3) {//如果第三個字段相等,就按第一個字段降序
         a._1>b._1
        }else{
        a._3<b._3 //否則第三個字段降序
        }
      }
    }
    //打印結果
    b.map(println)
從上面可以看出,基於sortBy的第二種實現比較優雅,語義比較清晰,第三種靈活性更強,但代碼稍加繁瑣

例子三:基於類的排序

先看sortBy的實現方法 排序規則:先按年齡排序,如果一樣,就按照名稱降序排

case class Person(val name:String,val age:Int)
 
    val p1=Person("cat",23)
    val p2=Person("dog",23)
    val p3=Person("andy",25)
    
    val pairs = Array(p1,p2,p3)
 
   //先按年齡排序,如果一樣,就按照名稱降序排
   val bx= pairs.sortBy(person => (person.age, person.name))( Ordering.Tuple2(Ordering.Int, Ordering.String.reverse) )
 
    bx.map(
      println
    )
結果:

Person(dog,23)
Person(cat,23)
Person(andy,25)
再看sortWith的實現方法:

case class Person(val name:String,val age:Int)
 
    val p1=Person("cat",23)
    val p2=Person("dog",23)
    val p3=Person("andy",25)
 
    val pairs = Array(p1,p2,p3)
 
    val b=pairs.sortWith{
      case (person1,person2)=>{
        person1.age==person2.age match {
          case true=> person1.name>person2.name //年齡一樣,按名字降序排
          case false=>person1.age<person2.age //否則按年齡升序排
        }
      }
    }
    b.map(
      println
    )
結果:

Person(dog,23)
Person(cat,23)
Person(andy,25)
總結:

本篇介紹了scala裏面的三種排序函數,都有其各自的應用場景:

sorted:適合單集合的升降序

sortBy:適合對單個或多個屬性的排序,代碼量比較少,推薦使用這種

sortWith:適合定製化場景比較高的排序規則,比較靈活,也能支持單個或多個屬性的排序,但代碼量稍多,內部實際是通過java裏面的Comparator接口來完成排序的。

實際應用中,可以根據具體的場景來選擇合適的排序策略。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章