【问题标题】:Scala sorting by rankingScala按排名排序
【发布时间】:2020-05-15 09:49:54
【问题描述】:

我尝试根据某个标准对复杂结构的案例类进行排序,该标准具有几个(有限数量)特征。排序应该按照排名表进行。

通过以下示例进行说明: 我有一个带有 bird 字段的工件,它可以将表达式 blackbird、starling、raven、budgie 作为字符串。序列应该按顺序排序(不是按字母顺序)

  1. 椋鸟
  2. 黑鸟
  3. 小伙伴们
  4. 乌鸦

鸟类本身可能相互依赖,因此不能改变组内的顺序。

到目前为止,我尝试的是首先对它们进行分组,然后对这些组进行排序并将它们重新拼凑在一起。然而它看起来很笨拙,出现了两个问题:

  1. groupBy 会一直保持之前的顺序吗?通过查看 ScalaDoc 参考,在我看来它会。
  2. 有没有比以下更有效/不那么笨拙的方法来对组进行排序:

编辑:添加了一个完整的例子,修复了一个问题

case class Abc(bird: String)
val grouped = Seq(Abc("budgies"), Abc("ravens"), Abc("starlings"), Abc("ravens"), Abc("starlings"), Abc("blackbirds"), Abc("blackbirds"), Abc("ravens"))
val lookup: Map[String, Int] = Map(
  "starlings" -> 1,
  "blackbirds" -> 2,
  "budgies" -> 3,
  "ravens" -> 4
)

object MyOrdering extends Ordering[Abc] {
  def compare(a: Abc, b: Abc): Int = lookup(b.bird) - lookup(a.bird)
}

println(grouped.toSeq.sorted(MyOrdering))

【问题讨论】:

    标签: scala sorting


    【解决方案1】:

    如果Abc 的顺序是固定的,它可能看起来像这样:

    case class Abc(bird: String)
    
    object Abc {
      implicit val ord: Ordering[Abc] =
        Ordering.by(abc => lookup.getOrElse(abc.bird, 0))
    
      val lookup: Map[String, Int] = Map(
        "starlings" -> 1,
        "blackbirds" -> 2,
        "budgies" -> 3,
        "ravens" -> 4
      )
    }
    
    val grouped = Seq(Abc("budgies"), Abc("ravens"), Abc("starlings"), Abc("ravens"), Abc("starlings"), Abc("blackbirds"), Abc("blackbirds"), Abc("ravens"))
    
    println(grouped.sorted)
    

    如果有不同的排序,那么Ordering.by 仍然是创建不同排序标准的好方法。

    大多数标准排序算法都是稳定的,这意味着根据排序相等的任何元素都将保持在排序之前的顺序。

    【讨论】:

    • 感谢您的回答。我将其标记为已接受,因为它提到了我所要求的稳定与不稳定的排序行为。
    【解决方案2】:

    这是否接近您所追求的?从您有限的描述中很难判断。

    val lookup: Map[String, Int] = 
      Map("starlings"  -> 1
         ,"blackbirds" -> 2
         ,"budgies"    -> 3
         ,"ravens"     -> 4).withDefaultValue(999)
    
    case class CC(bird :String)
    
    List(CC("ravens"),CC("starlings"),CC("budgies")) //etc.
      .sortBy(cc => lookup(cc.bird))
    

    【讨论】:

    • 有点,因为它不那么冗长,谢谢:) 我希望有人会提出不同的方法,但我想我现在会采用这个解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-18
    • 2015-10-25
    • 1970-01-01
    • 2014-08-07
    • 2019-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多