Question

Seeking a more elegant solution

I have this piece of code, I just use it in test cases where it isn't necessary to do any error handling. What it does is:

  • take an input list of strings
  • parse them using the DSJSonmapper.parseDSResult method
  • filters them and extracts the Right value from each Either (Left is an Exception)

The code is as follows:

  def parseDs(ins: List[String]) = {
    def filterResults[U, T](in: List[Either[U, T]]): List[T] = {
      in.filter(y => y.isRight).map(z => z.right.get)
    }
    filterResults(ins.map(x => DSJsonMapper.parseDSResult(x)))
  }

Now, I haven't done an awful lot of polymorphic functions, but this works. However I feel like it's a bit ugly. Has anyone got a better suggestion, how to accomplish the same thing.

I'm aware this is going to come down to a case of personal preference. But suggestions are welcome.

Was it helpful?

Solution

collect is made for exactly this kind of situation:

def filterMe[U,T](in: List[Either[U,T]]): List[T] = in.collect{
  case Right(r) => r
}

In fact, it's so good at this you may want to skip the def and just

ins.map(DSJsonMapper.parseDsResult).collect{ case Right(r) => r }

OTHER TIPS

Rex's answer is possibly a little clearer, but here's a slightly shorter alternative that parses and "filters" in a single step:

ins.flatMap(DSJsonMapper.parseDSResult(_).right.toOption)

Here we take the right projection of each parse result and turn that into an Option (which will be None if the parse failed and Some(whatever) otherwise). Since we're using flatMap, the Nones don't appear in the result and the values are pulled out of the Somes.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top