如何根据多个因素对 Scala 中的“映射”值进行排序?

Posted

技术标签:

【中文标题】如何根据多个因素对 Scala 中的“映射”值进行排序?【英文标题】:How to sort 'Map' values in Scala against multiple factors? 【发布时间】:2021-11-07 05:25:51 【问题描述】:

我有一个具有以下数据结构的 Map(数据类型):

var timePassedCamerasetB = mutable.Map.empty[String, Time];

它包含一个字符串和一个“时间”对象。 “时间”对象由我自己的类组成。您可以在下面看到它的组成:

case class Time(daysSinceEpoch: Int, hours: Int, minutes: Int, seconds: Double)

我已将所有数据保存到此“地图”变量中。但是有一个问题:我想根据多个事物对这个“地图”变量中的值进行排序,但是我找不到任何方法让它起作用。

例如。我在这张地图中存储了以下数据:

PP-33-XX -> Time(18492,3,7,0.0)
BA-12-PW -> Time(18492,9,0,40.0)
MM-11-OW -> Time(18492,3,7,16.0)
NX-66-PP -> Time(18492,3,6,30.0)
LA-53-NY -> Time(18492,9,0,56.0)

我想按顺序(最早时间到最晚时间)对值进行排序。这包括比较多个因素。首先比较每一天SinceEpoch,然后比较小时、分钟和秒。

我想把地图转换成下面的样子:

NX-66-PP -> Time(18492,3,6,30.0)
PP-33-XX -> Time(18492,3,7,0.0)
MM-11-OW -> Time(18492,3,7,16.0)
BA-12-PW -> Time(18492,9,0,40.0)
LA-53-NY -> Time(18492,9,0,56.0)

有没有人知道一种有效的方法来做到这一点?可惜我做不到..

【问题讨论】:

Maps 本质上是无序的集合,为什么要关心顺序呢?无论如何,您最终可能会使用List 之类的序列,然后使用orderBy 感谢您的快速回复!我明白这一点。出于教育原因,订单对我来说非常重要。我明白你的想法,但你能通过代码解释一下吗?也许我会更好地理解它。最终目标是将排序后的值再次保存在“Map”数据类型中(如上图所示)。 @LuisMiguelMejíaSuárez 我相信 jwvh 的答案会朝着您正在寻找的方向发展。一般来说,Maps 没有排序,但具体的实现可以保留插入顺序(如ListMaps 或LinkedHashMaps)或通过键保持排序(如TreeSets)。我不知道标准库中维护按值排序的 Map 实现。 【参考方案1】:

正如 Luis 评论的那样,地图,特别是 mutable.Map 并非旨在保存有序值。如果您可以使用列表,则可以像这样轻松排序:

timePassedCamerasetB
    .toList
    .sortBy 
      case (_, time) => (time.daysSinceEpoch, time.hours, time.minutes, time.seconds)
    

这个表达式必须被赋予新的值

【讨论】:

【参考方案2】:

听起来ListMap 就是你想要的。

来自ScalaDocs page:“条目在内部以相反的插入顺序存储,这意味着最新的键位于列表的头部。”

所以要从当前的Map 转换为ListMap

import scala.collection.immutable.ListMap

val newMap: ListMap[String,Time] = 
  oldMap.toList.sortBy
    case (_, Time(d,h,m,s)) => (d,h,m,s)
  .foldLeft(ListMap[String,Time]())(_+_)

测试:

newMap.head //res0: (NX-66-PP,Time(18492,3,6,30.0))
newMap.last //res1: (LA-53-NY,Time(18492,9,0,56.0))
newMap("MM-11-OW")    //res2: Time(18492,3,7,16.0)

【讨论】:

以上是关于如何根据多个因素对 Scala 中的“映射”值进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Scala 中的映射键中获取值的常见元素?

如何根据python中的多个条件对excel文件进​​行重复数据删除?

如何访问存储在scala spark中的数据框中的映射值和键

如何根据spark scala中的条件进行累积和

如何在Scala中访问嵌套映射中的键值

Scala RDD 映射