scala directly map fields of sequence elements

Viewed 111

I have a collection with elements that have a field field1. I want to get all field1s that are options of type MyType.

Currently this is my code.

elems.map(_.field1).map {case Some(found: MyType) => found}

I'm sure this can be done in a much nicer way.. It bugs me that I need to use map twice. Is there a way to do this with only one map/collect ?

EDIT: My code works. I'm just wondering if it can be done in a better (i.e. shorter or prettier way).

4 Answers

elems.flatMap(_.field1.collect { case x: MyType => x })

I believe utilising .flatMap may solve this issue for you

elems.flatMap(_.field1 match {
  case myType: MyType => Some(myType)
  case _              => None
}

Calling iterator before transforming the collection accumulates all the transformations into a single one so perhaps try

elems
  .iterator
  .flatMap(_.field1)
  .collect { case v: MyType => v }
  .toList

if your Seq type is case class you can use pattern matching with one collect function like so (see actual seq):

case class MyTypeWrapper(field1: Option[MyType])
case class MyType(x: String)

val elems                 = Seq.empty[MyTypeWrapper]
val expected: Seq[MyType] = elems.map(_.field1).map{ case Some(found: MyType) => found }

val actual: Seq[MyType] = elems.collect{ case MyTypeWrapper(Some(mt: MyType)) => mt }
// expected and actual should contains the same elements
Related