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
?)
You should use find
method on sequences. Generally you should prefer built-in methods, because they might be optimised for a specific sequence.
Console println List(1,2,3,4,5).find( _ == 5) res: Some(5)
That is, to return first SimpleDateFormat that match:
val str = "1903 January" val formats = List("MMM yyyy", "yyyy MMM", "MM yyyy", "MM, yyyy") .map(new SimpleDateFormat(_)) formats.find { sdf => sdf.parse(str, new ParsePosition(0)) != null } res: Some(java.text.SimpleDateFormat@ef736ccd)
To return first date that has being processed:
val str = "1903 January" val formats = List("MMM yyyy", "yyyy MMM", "MM yyyy", "MM, yyyy").map(new SimpleDateFormat(_)) val result = formats.collectFirst { case sdf if sdf.parse(str, new ParsePosition(0)) != null => sdf.parse(str) }
or use lazy collection:
val str = "1903 January" val formats = List("MMM yyyy", "yyyy MMM", "MM yyyy", "MM, yyyy").map(new SimpleDateFormat(_)) formats.toStream.flatMap { sdf => Option(sdf.parse(str, new ParsePosition(0))) }.headOption res: Some(Thu Jan 01 00:00:00 EET 1903)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With