【问题标题】:Scala Sort List[(String, Double)]Scala 排序列表[(String, Double)]
【发布时间】:2021-02-21 23:59:40
【问题描述】:

我试图在 Scala 中先按 Double 和 String 对 List[(String, Double)] 进行排序。这意味着我希望列表首先按 Double 的大小排序,然后按字母顺序排列。

例如,

val sortThisList = List[("C", 2.0), ("B", 1.0), ("A", 1.0), ("B", 2.0), ("A", 2.0), ("C", 1.0)]

sortThisList 排序后应如下所示:

List[("A", 2.0), ("B", 2.0), ("C", 2.0), ("A", 1.0), ("B", 1.0), ("C", 1.0)]

我尝试过使用 sortBy 函数:

val sortedList = sortThisList.sortBy(_._2).sortBy(_._1)

这是我尝试使用 sortBy 和 sortWith 编译的唯一版本。但是,它只会产生一个按字母顺序排序的 sortedList 版本,而不是先按 Double 的大小再按字母顺序排序。

【问题讨论】:

  • 你试过什么?为什么它不起作用?你至少看过scaladoc吗?
  • 我无法重现您的问题。当我尝试您的代码时,我得到“方法应用的类型参数数量错误:[A](elems: A*): List[A] in trait IterableFactory”。

标签: list scala sorting


【解决方案1】:

您的代码几乎是正确的,但您需要按相反的顺序排序并将双精度数取反以从高到低排序:

sortThisList.sortBy(_._1).sortBy(-_._2)

这是可行的,因为 Scala 排序是稳定,这意味着如果排序值相同,则值保持相同的顺序。所以第一个sortBy 确保字符串是有序的,第二个sortBy 按双打排序(反向)。如果有多个记录具有相同的双精度值,则它们仍然按字符串值排序。

但是,这可以使用 sortBy 在单个操作中完成:

sortThisList.sortBy(e => (-e._2, e._1))

这通过按优先级顺序提取字段并按该值排序来工作。

【讨论】:

    【解决方案2】:

    想通了。

    val listByValue = sortThisList.groupBy { case (key, value) => value }.toSeq
    val listByValue = listByValue.sortBy { case (value, group) => value }
    val sortedList = listByValue.flatMap { case (key, value) => value.sortBy { case (key, value) => value } }.reverse.toList
    

    【讨论】:

    • 您发布的解决方案无法编译。
    【解决方案3】:

    您的问题是由拼写错误引起的:

    val sortThisList = List[("C", 2.0), ("B", 1.0), ("A", 1.0), ("B", 2.0), ("A", 2.0), ("C", 1.0)]
    

    这行不通。您正在做的是传递六个 类型参数,它们是成对的文字类型。您可能想要传递 值参数。在 Scala 中,就像在几乎所有编程语言中一样(是的,我知道,有 Rebol),值参数在圆括号中传递,而不是方括号。

    【讨论】:

    • 你对两种效果的说法不正确。 Scala 排序是稳定的,因此在第一次排序中完成的任何排序都会保留给第二次排序值相同的记录。所以这个问题的一个答案是sortThisList.sortBy(_._1).sortBy(_._2)(正如我在回答中解释的那样)。
    • 也不会产生正确的答案,因为Double 值应该从高到低排序,而不是从低到高排序。
    猜你喜欢
    • 2019-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-15
    • 1970-01-01
    • 2011-07-06
    • 1970-01-01
    相关资源
    最近更新 更多