【问题标题】:Scala - how to sort tuples by both attributes in different order?Scala - 如何按两个属性以不同的顺序对元组进行排序?
【发布时间】:2020-04-02 11:56:05
【问题描述】:

我想对List[(String, Int)] 进行排序,以便首先按降序对 Int 进行排序,然后按字母顺序对字符串进行排序。通过我当前的实现,我按预期实现了对 Ints 的排序。但是字符串以相反的顺序排序。我想这是由于应用于整个元组的反向排序。

我应该如何更正此问题以使字符串按字母顺序排序?

val list: List[(String, Int)] = List(("x", 1), ("a", 1), ("c", 1), ("a", 2), ("b", 2), ("b", 1), ("a", 5), ("c", 5))
val sortedList = list.sortBy(x => (x._2, x._1))(implicitly[Ordering[(Int, String)]].reverse)

// Prints List((c,5), (a,5), (b,2), (a,2), (x,1), (c,1), (b,1), (a,1))
println(sortedList)

Expected: List((a,5), (c,5), (a,2), (b,2), (a,1), (b,1), (c,1), (x,1)) 

【问题讨论】:

标签: scala sorting collections


【解决方案1】:
scala> val sortedList = list.sortBy(x => (-x._2.toLong, x._1))
sortedList: List[(String, Int)] = List((a,5), (c,5), (a,2), (b,2), (a,1), (b,1), (c,1), (x,1))

toLong 的诀窍是适用于任意 Int 值,包括 Int.MinValue,其中:

scala> Int.MinValue == -Int.MinValue
res0: Boolean = true

scala> Int.MinValue.toLong == -Int.MinValue.toLong
res1: Boolean = false

为了在运行时减少分配并提高效率,请考虑使用带有自定义排序功能的sorted:

scala> :paste
// Entering paste mode (ctrl-D to finish)

  list.sorted((x: (String, Int), y: (String, Int)) => {
    if (y._2 > x._2) 1
    else if (y._2 < x._2) -1
    else x._1.compareTo(y._1)
  })

// Exiting paste mode, now interpreting.

res2: List[(String, Int)] = List((a,5), (c,5), (a,2), (b,2), (a,1), (b,1), (c,1), (x,1))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-25
    • 1970-01-01
    • 2023-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-24
    • 2019-10-02
    相关资源
    最近更新 更多