I'm writing some code to parse a CSV file where I simply want to throw away any records that don't have the right format. I'm using Scala Try() to wrap the extraction process for each line of input data, which produces a sequence of Try's. Then I filter these and do a get() on the Successes to create a list of my required class instances. But I'm wondering if there's a more idiomatic way of extracting the results from the sequence of Try's.
Here is a simplified version of my code, which reads Strings from an imaginary CSV file, and wants to convert them to a Fubar which has 3 Int fields. I know it's not the done thing, but in this case I'm not interested in trapping any parsing exceptions - I just want the valid data.
Now I can run this code with some dummy data:
Results from Step 1 are fine:
Now run the second step:
The end results are exactly what I want i.e. a sequence of valid instances of Fubar:
So my code does what I want and it's pretty concise, but I still think there is vague code-smell around the Try/Success processing. Anybody got any better ideas?
Thanks, Maxim. I like the idea of turning the Try into an Option and using flatMap, as it's easier to handle consistently but still makes it easy enough to respond to errors if necessary. I'd feel a bit less comfortable simply swallowing the exception, as in your second example, even though I'm not interested in errors currently.
Thanks for the helpful suggestions - it's good to get input from other people as this stuff is still pretty new to me!
We actually had a similar dilemma and after some time settled on using ScalaZ disjunctions. They are composable, don't swallow exceptions (unless you ask them to), can be converted to Option's etc. I even wrote a blog post about it a couple of months ago:
My idea from reading Programming in Scala recently (new edition just came out) is that the idiomatic way of doing it is with the "collect" function which is the equivalent of filter + map in one function.
You could just change getSuccessful to something like this and preserve the rest as is:
But I think completely idiomatic usage would be to use a deep pattern match and do it all in one collect statement:
My honeysuckle is blooming this year! Now to fertilize this tiny ad: