How to gracefully handle the "Key not found" on the Scala map?

In general, I need a functional way to do one thing if the value was found on the Map and Do another thing if it was not found. Note that I'm not interested in the return value, but the action is complete.

Read more.

I have a service name map (friendly) to the PATH part of the URL (not just to remember). Here is the initialization.

val serviceMap = Map("read" -> "cryptic-read-path",
  "save" -> "cryptic-save-path", "county" -> "cryptic-zip-code-to-county-service.");

All the alternatives that I know, lead to an if statement with the loaded part then, but simple 404 else. Here are some of them that I was thinking about

if (serviceMap.contains(service)) {
    //Do stuff
} else {
    //Issue a 404
}

This is equivalent to the inverse predicate

if (!serviceMap.contains(key)) //issue a 404
//Do stuff

Both of the above approaches require me to check-receive-receive.

( )

  serviceMap.get(service) match {
  case _ : Option[String]=> //Do stuff
  case _  => //issue 404
}

,

  serviceMap.get(service).forEach {//Dostuff and return, since it just one element }
  //issue 404 if you are here.

Per , Option , , forEach .

, . , , ? !

+4
5

, :

  • match unapply ( _ : Option[CantTellWhatThisIsAtRuntime]):

    serviceMap.get(service) match {
      case Some(path) => // Do stuff and return
      case _ => // 404
    }
    
  • fold ( , 404 ):

    serviceMap.get(service).fold(/* 404 */) { path =>
      // Do stuff and return
    }
    
  • map + getOrElse, / 404 ( Mikesname):

    serviceMap.get(service).map { path =>
      // Do stuff and return
    } getOrElse {
      // 404
    }
    
  • map getOrElse (, 404):

    val path = serviceMap.getOrElse(service, throw Error404)
    // Do stuff and return
    
+2

, map getOrElse:

val result = serviceMap.get(service).map { url =>
  // do something with url
} getOrElse {
  // not found
}

, Option ( ), .

+3

. .

serviceMap.get(service) match {
  case Some(s) => println("Here my string from the map! " + s)
  case _ => //issue 404
}

, . , - , , "cryptic-read-path", :

serviceMap.get(service) match {
  case Some("cryptic-read-path") => //do stuff that is specific for cryptic read path
  case Some(s) => println("Here my string from the map! " + s)
  case _ => //issue 404
}

foreach. , .

: , :

serviceMap.get(service) match {
  case Some(_) => //do stuff
  case _ => //issue 404
}
+3

- . Option , , . match, .

, , , , Option :

 val response = serviceMap.get(service).map { value =>
   // do stuff to convert into a 200 response
 }.getOrElse {
   // create 404 response
 }

map Some[String] Some[Response], None. , Option[Response], getOrElse, 404 None.

+1

Map , , ,

val a = Map( 1->2, 3->4)

a

a.lift
Int => Option[Int] = <function1>

a.lift(1)
Option[Int] = Some(2)

a.lift(0)
Option[Int] = None

, , a , ,

val ok = for { v <- a.lift(1); res <- Some(awesome_stuff(v)) }
         yield res

ok getOrElse report404

v res ( , None), ok None.

+1

Source: https://habr.com/ru/post/1605613/


All Articles