Scala如何为List对象的maxBy方法设置多重排序优先级
方案一:简洁单行实现
利用Scala元组的默认排序规则,一行即可完成需求:
val bestBook = books.sortBy(book => (-scores(book.bookID), book.bookName)).head
- 第一个排序键取
-scores(book.bookID):sortBy默认按升序排序,添加负号后评分越高的书籍排序越靠前 - 第二个排序键取
book.bookName:评分相同时,自动按书名的字母升序排序 - 取排序后列表的第一个元素即为符合要求的最优书籍
方案二:自定义Ordering复用规则
如果需要在多处使用相同的书籍排序逻辑,可以自定义隐式Ordering,后续直接调用max方法即可:
// 定义排序规则:优先按评分降序,评分相同按书名升序 implicit val bookOrdering: Ordering[Book] = Ordering.by[Book, Float](book => scores(book.bookID)).reverse.thenBy(_.bookName) // 直接调用max获取最优书籍 val bestBook = books.max
- 先用
Ordering.by构造基于评分的升序排序规则,调用reverse转为降序 - 调用
thenBy追加第二个排序规则:按书名升序 - 定义为隐式变量后,所有针对Book类型的排序、取极值操作都会默认使用该规则,无需重复编写逻辑
方案三:O(n) 高性能实现(适用于大数据量场景)
如果书籍列表量级极大,想要避免排序的O(n log n)开销,可以用reduce实现单次遍历取最优:
val bestBook = books.reduce { (a, b) => val scoreA = scores(a.bookID) val scoreB = scores(b.bookID) if (scoreA > scoreB) a else if (scoreA < scoreB) b else if (a.bookName.compareTo(b.bookName) < 0) a else b }
内容的提问来源于stack exchange,提问作者jeb2
相关产品推荐
相关产品推荐

