天天看點

spark多字段排序與取topN

項目github位址:bitcarmanlee easy-algorithm-interview-and-practice

歡迎大家star,留言,一起學習進步

1.多字段排序

前面介紹了[k,v]結構的rdd排序方法,下面來看更為複雜的情況,如果有更為複雜的多字段排序需求該怎麼處理?

比如有如下資料

1 2
1 3
1 1
1 6
1 4
2 5
2 8
2 3
           

我們現在想先對第一列逆序排,如果第一列相同再按第二列逆序排,該怎麼辦呢?

以下兩種方式都可以滿足上面的需求

1.1 定義SecondSortKey來實作

首先我們定義一個SecondSortKey

class SecondSortKey(val first: Int, val second: Int) extends Ordered[SecondSortKey] with Serializable {
        override def compare(that: SecondSortKey): Int = {
            if (this.first -that.first == 0) {
                this.second - that.second
            } else {
                this.first - that.first
            }
        }
    }
           

然後按如下方式即可實作:

val lines = sc.parallelize(Array((1, 2), (1, 3), (1, 1), (1, 6), (1, 4), (2, 5), (2, 8), (2, 3)))
        lines.map { x => (new SecondSortKey(x._1, x._2), x) }
            .sortByKey(ascending = false)
            .map(_._2)
            .collect()
           

2.不建立對象,通過自定義Ordering來實作

首先我們在方法中定義隐變量ordering:

implicit val ordering = new Ordering[(Int, Int)] {
            override def compare(a: (Int, Int), b: (Int, Int)) = {
                var result = 0
                if (a._1 == b._1) {
                    result = a._2 - b._2
                } else {
                    result = a._1 - b._1
                }
                result
            }
        }
           

然後按如下方式使用即可

val a = sc.parallelize(Array((1, 2), (1, 3), (1, 1), (1, 6), (1, 4), (2, 5), (2, 8), (2, 3)))
        a.map { x => (x, x) }.sortByKey(ascending = false).map(_._2).collect()
           

2.取topN

還是上面的例子,比如我們要按第二列取top3

a.sortBy(_._2, ascending = false).take(3)
           

繼續閱讀