Reputation: 83
I have a
val timestampOffsetMap: Map[ZonedDateTime, Int]
would like to search nearest before timeStamp( a.k.a ZonedDateTime) to getOffset
def getNearestBeforeTimeStampOffset(timeToCheck: ZonedDateTime): Int = ???
I know about sortedMap and thinking about using it, but not sure if there is a better way to solve the problem. Also I am on scala 2.11 for collections API
Upvotes: 2
Views: 272
Reputation: 44957
Update
As Joe Pallas has pointed out, scala's default implementation of TreeMap
provides essentially the same functionality as Java's NavigableMap
. However, the API is quite different: on TreeMap
, there are methods from
, to
and range
, that create ranged projections of the TreeMap
. On these ranged projections, the methods headOption
and tailOption
can be used to select elements that essentially correspond to ceil
and floor
-elements of a given key.
The reason why the API looks quite different (it returns entire trees instead of a single ceil
/floor
-elements), is that, somewhat counter-intuitively, building a ranged projection of an immutable tree is asymptotically just as expensive as retrieving a single element.
Nevertheless, I think that there is nothing wrong with using a Java collection for such a specific task, especially if the API is more intuitive. I also suspect that Java's implementation might actually be a tiny bit faster and produce less garbage (that's a speculation, I didn't measure it).
Original answer
Java standard collections provide implementations of NavigableMap
, with java.util.TreeMap
being one example. The NavigableMap
provides methods like floorKey
, floorEntry
, ceilingKey
and ceilingEntry
, which seem to do exactly what you want:
import java.util.TreeMap
import java.time.ZonedDateTime
val tm = new TreeMap[ZonedDateTime, Int] // + add entries
def getNearestBeforeTimeStampOffset(timeToCheck: ZonedDateTime)
: Int = tm.floorEntry(timeToCheck).getValue
I'm not sure whether Scala's TreeMap
provides a similar functionality, at least it's not called anything with "ceiling" or "floor" in the name. This eternally old question here also didn't point immediately to the functionality analogous to NavigableMap
, so maybe it's easier to just use Java's TreeMap
in this case.
To convert scala Map
to java.util.TreeMap
, something like this should work:
val yourMap: Map[ZonedDateTime, Int] = ???
import scala.collection.JavaConverters._
val tm = new java.util.TreeMap((yourMap.asJava : java.util.Map[ZonedDateTime, Int]))
Upvotes: 2