I have a Map (datatype) with the following data structure:
var timePassedCamerasetB = mutable.Map.empty[String, Time];
It contains a String and a 'Time' object. The 'Time' object is made up from my own class. Below you can see what it consists of:
case class Time(daysSinceEpoch: Int, hours: Int, minutes: Int, seconds: Double)
I have saved all my data into this 'Map' variable. But there is one problem: I want to sort the values in this 'Map' variable based on multiple things, but I can't find any way to make it work.
For example. I have stored the following data within this 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)
I want to sort the values in order (earliest time to latest time). This includes comparing multiple factors. First compare each daysSinceEpoch, then hours, minutes and seconds.
I want to transform the map into the following down below:
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)
Does anyone know of an efficient way to do this? Unfortunately I can't..
CodePudding user response:
As Luis commented, Maps, specifically mutable.Map
aren't designed to hold ordered values. If you could go with a List it can be easily sorted like this:
timePassedCamerasetB
.toList
.sortBy {
case (_, time) => (time.daysSinceEpoch, time.hours, time.minutes, time.seconds)
}
This expression has to be assigned to new value
CodePudding user response:
It sounds like a ListMap
is what you want.
From the ScalaDocs page: "Entries are stored internally in reversed insertion order, which means the newest key is at the head of the list."
So to transit from the current Map
to a 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]())(_ _)
testing:
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)