2016-07-30 14 views
1

Gibt es eine idiomatische/einfachere Möglichkeit, diesen Code zu schreiben, der zwei Optionen behandelt?Bedingte Logik bei der Auswertung von zwei Optionen

object Test extends App { 
    val colors = Some(1) 
    val sizes = Some(2) 

    val ids = colors match { 
    case None => { 
     sizes match { 
     case None => getRegularIds 
     case Some(sizes) => getSizeIds 
     } 
    } 
    case Some(colors) => { 
     sizes match { 
     case None => getColorIds 
     case Some(sizes) => getColorIds ++ getSizeIds 
     } 
    } 
    } 

    println(ids) 

    def getColorIds = Seq(1,2,4) 
    def getSizeIds = Seq(4,5,6) 
    def getRegularIds = Seq(7,8,9) 
} 

Scala ist so präzise, ​​dass es führt mich zu denken, ist wahrscheinlich ein sauberer Weg, um die gleichen Ergebnisse zu erzielen. Vielen Dank für Ihre Zeit.

Antwort

2

Vermeiden Sie verschachtelte Matching:

val ids2 = (colors, sizes) match { 
    case (None, None)  => getRegularIds 
    case (Some(_), None) => getColorIds 
    case (None, Some(_)) => getSizeIds 
    case (Some(_), Some(_)) => getColorIds ++ getSizeIds 
} 

Sie könnten auch versuchen, so etwas wie:

colors.fold(defaultColors)(_ => getColors) ++ 
    sizes.fold(defaultSizes)(_ => getSizes) 
+0

Danke für die Eingabe. Viel sauberer. – user455497

+0

Auf der anderen Seite ist verschachtelte Logik schneller, da es zu einer flacheren Verzweigung führt. –

+0

@PaulDraper Auch wenn dies der Fall ist, überwiegen diese 0,0000001% Leistungssteigerung die Wartbarkeit nicht. – ipoteka

0

Wenn Ihr Seq s sind List s, können Sie auch mit Scalaz der Halbgruppen tun dies anzuhängen, direkt aus die Box:

import scalaz._, Scalaz._ 

scala> (colors.map(_ => getColorIds) |+| sizes.map(_ => getSizeIds)) 
     .getOrElse(getRegularIds) 
res11: List[Int] = List(1, 2, 4, 4, 5, 6) 

Hier sind die anderen Ergebnisse (e xplicitly) zu zeigen, was los ist:

scala> (Option(List(1, 2, 4)) |+| Option.empty[List[Int]]).getOrElse(getRegularIds) 
res14: List[Int] = List(1, 2, 4) 

scala> (Option.empty[List[Int]] |+| Option(List(4, 5, 6))).getOrElse(getRegularIds) 
res15: List[Int] = List(4, 5, 6) 

scala> (Option.empty[List[Int]] |+| Option.empty[List[Int]]).getOrElse(getRegularIds) 
res16: List[Int] = List(7, 8, 9) 

Leider gibt es keine Semigroup[Seq]. Eine bessere Erklärung, warum nicht, siehe this answer.

Verwandte Themen