如何根据多个因素对 Scala 中的 'Map' 值进行排序?
How to sort 'Map' values in Scala against multiple factors?
我有一个具有以下数据结构的地图(数据类型):
var timePassedCamerasetB = mutable.Map.empty[String, Time];
它包含一个字符串和一个 'Time' 对象。 'Time' 对象是由我自己的 class 组成的。您可以在下面看到它由什么组成:
case class Time(daysSinceEpoch: Int, hours: Int, minutes: Int, seconds: Double)
我已将所有数据保存到这个 'Map' 变量中。但是有一个问题:我想根据多种因素对这个 'Map' 变量中的值进行排序,但我找不到任何方法让它工作。
例如。我在这张地图中存储了以下数据:
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)
我想按顺序对值进行排序(最早时间到最晚时间)。这包括比较多个因素。首先比较每个daysSinceEpoch,然后比较小时、分钟和秒。
我想把地图改成下面的样子:
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)
有谁知道执行此操作的有效方法吗?可惜我不能..
正如 Luis 评论的那样,地图,特别是 mutable.Map
并非旨在保存有序值。如果你可以使用列表,它可以像这样轻松排序:
timePassedCamerasetB
.toList
.sortBy {
case (_, time) => (time.daysSinceEpoch, time.hours, time.minutes, time.seconds)
}
这个表达式必须赋给新值
听起来 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)
我有一个具有以下数据结构的地图(数据类型):
var timePassedCamerasetB = mutable.Map.empty[String, Time];
它包含一个字符串和一个 'Time' 对象。 'Time' 对象是由我自己的 class 组成的。您可以在下面看到它由什么组成:
case class Time(daysSinceEpoch: Int, hours: Int, minutes: Int, seconds: Double)
我已将所有数据保存到这个 'Map' 变量中。但是有一个问题:我想根据多种因素对这个 'Map' 变量中的值进行排序,但我找不到任何方法让它工作。
例如。我在这张地图中存储了以下数据:
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)
我想按顺序对值进行排序(最早时间到最晚时间)。这包括比较多个因素。首先比较每个daysSinceEpoch,然后比较小时、分钟和秒。
我想把地图改成下面的样子:
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)
有谁知道执行此操作的有效方法吗?可惜我不能..
正如 Luis 评论的那样,地图,特别是 mutable.Map
并非旨在保存有序值。如果你可以使用列表,它可以像这样轻松排序:
timePassedCamerasetB
.toList
.sortBy {
case (_, time) => (time.daysSinceEpoch, time.hours, time.minutes, time.seconds)
}
这个表达式必须赋给新值
听起来 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)