Conquest
Conquest

Reputation: 285

Scala skip when key not found in map

I am trying to do the following for the case when I do not find the key in a Map

val states = Seq(Ca, Wa, Ny)
val tuples: Seq[Any] = for(state <- states) yield {
  val mapValue: Option[CustomCaseClass] = someMap.get(key)
  mapValue match {
    case Some(value) => {
      //do some operations and return a tuple (String, String)
    }
    case _ => //do nothing, just continue the for loop
  }
}

For the case _ I want to do nothing and simple continue the loop. But with the above code, I am not able to do a toMap on tuples and I get the following error -

Cannot prove that Any <:< (String, String)

This is due to the fact that it may not always return Seq[(String,String)]. I want to be able to do operations on tuples and I simple want to skip the case when its not found. Any guidance is appreciated.

Upvotes: 0

Views: 1204

Answers (2)

Oleg Pyzhcov
Oleg Pyzhcov

Reputation: 7353

Assuming the following setup:

sealed trait State
case object Ca extends State
case object Wa extends State
case object Ny extends State

val someMap = Map(Ca -> 1, Wa -> 2)
val states = Seq(Ca, Wa, Ny)

We can use Option as another generator in the same for comprehension:

val tuples: Seq[(String, String)] = for {
    state <- states
    value <- someMap.get(state)
} yield (state.toString, value.toString + "x")

Option will be implicitly converted to a collection of 0 to 1 elements, so for None all the following code will be skipped and we will get this:

assert(tuples.toMap == Map("Ca" -> "1x", "Wa" -> "2x"))

You can also insert an arbitrary check inside for, so you can check for key presense and use someMap(key), not someMap.get(key):

val tuples2: Seq[(String, String)] = for {
    state <- states
    if someMap.contains(state)
} yield (state.toString, someMap(state).toString + "x")

assert(tuples2.toMap == Map("Ca" -> "1x", "Wa" -> "2x"))

Upvotes: 1

chengpohi
chengpohi

Reputation: 14217

Since case _ it's returning nothing so the result type is Seq[Any], you can filter the not found element and do the map:

val tuples: Seq[(String, String)] = 
    states.filter(i => someMap.get(i).nonEmpty).map(value => (myString, myString))

Upvotes: 0

Related Questions