2013-05-01 4 views
10

In scala zu geben, wenn Sie eine Option haben, können Sie eine weitere Option, indem Sie oldOption.map bekommen kann (_ etwas.). Ich möchte einen Booleschen Befehl ausführen und dasselbe tun. Mit anderen Worten, ich mag eine Abkürzung für den folgenden:Scala - "if (true) Einige (1)" ohne "sonst keine"

if(someCondition) 
    Some(data) 
else 
    None 

Gibt es einen idiomatischen Weg, um eine Option aus einem Booleschen wie diese zu erhalten, ohne „sonst None“ zu tun hat?

+0

möglich Duplikat [Vereinfachen if (x) Einige (y) sonst keine?] (Http://stackoverflow.com/questions/12728678/simplify-if-x-somey-else-none) – Suma

Antwort

12

Scalaz Dies hat. Der Code würde wie folgt aussehen:

import scalaz._ 
import Scalaz._ 
val b = true 
val opt = b option "foo" 

Die Art der opt wird Option[String]

16

Wenn Sie nichts dagegen haben die Daten zu schaffen, jedes Mal,

Some(data).filter(someCondition) 

den Trick. Wenn es Ihnen nichts ausmacht, die Daten jedes Mal neu zu erstellen,

aber ich glaube nicht, dass das klarer ist. Ich würde mit wenn-sonst gehen, wenn ich du wäre.

Oder Sie könnten

def onlyIf[A](p: Boolean)(a: => A) = if (p) Some(a) else None 

und dann

onlyIf(someCondition){ data } 
+0

One kleine Änderung: 'Option (someCondition) .filter (Identität) .map (_ => Daten)' – pedrofurla

+0

@pedrofurla - Ich finde den Vergleich zu wahren informativer als ein Identitätsfilter. Ich gebe zu, dass Identität vielleicht effizienter ist, aber wenn Sie nach Effizienz streben, würden Sie es auf diese Weise überhaupt nicht schreiben. –

+1

Ich liebe die 'onlyIf' Methode, aber ich wünschte, sie könnte zu einem neuen' Some' Objekt in 'scala.lang' hinzugefügt werden. Dann könnten Sie 'Some.onlyIf (x% 2 == 0) (x)' tun, um eine 'Option [Int]' zurückzugeben. Das ist wirklich nur nützlich, wenn das Ding in "Some" ziemlich kompliziert ist, was ich als 'Some.onlyIf (cond) {// viel Code hier}}' sehen kann. – TOB

3

Wie wäre es mit dem Feuer spielen:

implicit class CondOpt[T](x: => T) { 
    def someIf(cond: Boolean) = if (cond) Some(x) else None 
} 

Verwendung:

data someIf someCondition 

Nachteile:

  1. Dangerous, implizite Konvertierung von Any
  2. berechnet Daten jedes Mal
+0

Stellen Sie den Parameter "Name nach Name" ein, und die Daten werden nur berechnet, wenn sie benötigt werden. d.h.'implizite Klasse CondOpt [T] (x: => T)' –

+0

@LuigiPlinge Danke, ich habe es geändert. In der Tat, da es nur ein Parameter (kein Klassenwert) ist, kann es sich um den Namen handeln. – gzm0

2
import PartialFunction._ 
condOpt(someCondition) { 
    case true => data 
} 
sein

persönlich verwende ich dieses Muster eine Menge, wenn ich etwas extrahieren müssen, z.B.

val maybeInt: Option[Int] = condOpt(string) { 
    case AsInt(i) if i > 0 => i 
}