abroy
abroy

Reputation: 83

Scala simple way to search timeStamps in a Map of timestamps

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

Answers (1)

Andrey Tyukin
Andrey Tyukin

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

Related Questions