Reputation: 11666
How do I remove the oldest entries from a LinkedHashMap
without traversing the whole map or collecting keys in an intermediate collection? LinkedHashMap
entries are sorted by insertion order, so the oldest are found first when iterating. I'd like to do this:
userAndWhenMap.iterator.removeWhile { case (userId, userAndWhen) =>
now.millisSince(userAndWhen.when) > DeleteAfterInactiveMillis
}
But removeWhile
doesn't exist. There's a dropWhile
but it doesn't mutate the map — it advances an iterator. Is there no way to achieve something like removeWhile
?
(I know about retain
but it traverses the whole map. And I know I can find the keys I want to remove and insert them in a set and then loop through it and Map.remove(..)
.)
Upvotes: 0
Views: 57
Reputation: 8663
I think the only way is to implement your removeWhile method as an extension method for LinkedHashMap
class
There are only two methods that modify the this collection instead of returning new: retain
and transform
(I am ignoring ++=, +=, --= and -= here) and they don't do what you need.
here is example code:
implicit class LinkedHashMapOps[A, B](val self: LinkedHashMap[A, B]) extends AnyVal {
def removeWhile(predicate: ((A, B)) => Boolean): self.type = {
val toRemove = self.iterator.takeWhile(predicate).map(_._1)
toRemove foreach (self -= _)
self
}
}
and test:
@ val map = new LinkedHashMap[Int, String]
@ map += (1 -> "a")
@ map += (2 -> "a")
@ map += (3 -> "a")
@ map += (4 -> "a")
res6: LinkedHashMap[Int, String] = Map(1 -> "a", 2 -> "a", 3 -> "a", 4 -> "a")
@ map.removeWhile(_._1 < 3)
res8: LinkedHashMap[Int, String] = Map(3 -> "a", 4 -> "a")
Upvotes: 2