Ken
Ken

Reputation: 4887

Idiomatically return None if Option contains None or contains unwanted type

I want to read the head of an possibly empty list and if that head contains a specific pattern I will return Some(), in all other cases I want to return None.

Here is my working code, but it's a bit ugly with the nested matches and re-wrapping the object in a Some() after unwrapping it.

 list.headOption match{
  case None => None
  case Some(csvString) => csvString.split(',') match {
    case Array(a, b, c) => Some(Array(a, b, c))
    case _ => None
  }
}

Is there a nicer, more idiomatic way of achieving this?

Upvotes: 1

Views: 403

Answers (2)

user9223219
user9223219

Reputation:

In this particular case you may use .map:

list.headOption.map(_.split(','))

And if you need to make sure the array has only 3 elements, you can use a combination of .map and .filter:

list.headOption.map(_.split(',')).filter(_.length == 3)

Or test a specific pattern:

list.headOption.map(_.split(',')).filter {
  case Array(a, b, c) => true
  case _ => false
}

Upvotes: 3

Gabriele Petronella
Gabriele Petronella

Reputation: 108091

Using map and collect you can do

list.headOption.map(_.split(',')).collect {
  case values @ Array(a, b, c) => values
}

Upvotes: 5

Related Questions