Generally, how to find the first element satisfying certain condition in a Seq
?
For example, I have a list of possible date format, and I want to find the parsed result of first one format can parse my date string.
val str = "1903 January"
val formats = List("MMM yyyy", "yyyy MMM", "MM yyyy", "MM, yyyy")
.map(new SimpleDateFormat(_))
formats.flatMap(f => {try {
Some(f.parse(str))
}catch {
case e: Throwable => None
}}).head
Not bad. But 1. it's a little ugly. 2. it did some unnecessary work(tried "MM yyyy"
and "MM, yyyy"
formats). Perhaps there is more elegant and idiomatic way? (using Iterator
?)
If you're confident at least one will format will succeed:
If you want to be a bit safer:
Try
was introduced in Scala 2.10.A
view
is a type of collection that computes values lazily. It will apply the code within theTry
to only as many items in the collection as is necessary to find the first one that is defined. If the firstformat
applies to the string, then it won't try to apply the remaining formats to the string.This prevents the unnecessary evaluations.
The number of evaluations of the
parse
method is number of tries + 1.You should use
find
method on sequences. Generally you should prefer built-in methods, because they might be optimised for a specific sequence.That is, to return first SimpleDateFormat that match:
To return first date that has being processed:
or use lazy collection:
By the way, since
SimpleDateFormat
is non-thread-safe, that means the above code is not thread-safe either!I think using tail recursion is much better and by far the most efficient solution offered here so far:
It would allow you upon importing the above class to simply do the something like the following wherever you need to:
Best of luck!
Same version with Scala Extractor and lazyness: