2013-11-04 3 views
7

Ich habe einen Vektor von Vektoren, auf die ich zugreife, um eine boolesche Funktion anzuwenden. das heißtGibt es eine einfache Möglichkeit, in verschachtelten Seqs in Scala aus dem Rahmen zu gehen?

Vector[Vector[T]], wo ich etwas entlang der Linien von f(myVector(i)(j)) ausführen werde, wo f vom Typ T => Boolean.

Aber das überprüft Grenzen nicht, und ich kann etwas wirklich elegantes nicht bekommen.

kann ich applyOrElse verwenden: myVector.applyOrElse(i, (_:Int) => Vector.empty).applyOrElse (j, (_:Int) => defaultT)

wo f(defaultT)false zurückkehren würde, aber ich wünschte, ich nur einen Standardwert statt einer Funktion einstellen könnte.

I Lift benutzen könnte mir ein Option zu geben, aber sie besteht nicht gut auf der zweiten Ebene: myVector.lift(i) map (_.lift(j) map f getOrElse false) getOrElse false

Welche Arbeit leistet, aber immer noch sehr schwer zu lesen ist.

Und dann gibt es Standard-if/else Blöcke:

if (myVector.size <= i) false 
else { 
    val myVector2 = levelVector(i) 
    if (myVector2.size <= j) false 
    else f(myVector2(j)) 
} 

Es scheint nur, wie etwas, das in der Lage sein sollte, zerlegt werden leichter als das, was ich erreichen kann. Und wenn ich eine dritte Ebene hinzufüge, wird es noch hässlicher.

Gibt es andere Optionen?

Haftungsausschluss: Diese von Coursera des progfun natürlich angepasst ist

Antwort

2

Nehmen Sie den folgenden Code aus der Frage:

myVector.lift(i) map (_.lift(j) map f getOrElse false) getOrElse false 

Diese überschrieben werden können wie folgt:

myVector.lift(i).flatMap(_.lift(j)).fold(false)(f) 

Oder vor fold in Scala 2.10 eingeführt wurde:

myVector.lift(i).flatMap(_.lift(j)).map(f).getOrElse(false) 

Die Schlüsselidee besteht darin, das Auspacken (oder Mapping) des Option für wie lo zu verzögern so weit wie möglich. Dieser Ansatz wird sich ganz natürlich auf mehr als zwei Dimensionen erstrecken.

Das ist ziemlich nah an das entspricht dem for einen Sachverhalt in Ihrer Antwort (vorausgesetzt, Sie lift dort einschließen soll), aber wenn man das Verständnis in Klammern zu wickeln habe ich persönlich tendiere die entzuckert Version klarer zu finden.

+0

Fantastisch - Ich habe versucht, die Option zu halten, aber die Grundlagen des Listenverständnisses vergessen. Vielen Dank. – Stephen

+0

2.10 kürzere Version: 'myVector.lift (i) .flatMap (_. Lift (j)). Exists (f)' – lpandzic

0

Ich habe bezifferten etwas, das elegant scheint, auch wenn es ein bisschen übertrieben zu sein scheint:

(for { 
    myVector2 <- myVector(i) 
    t <- myVector2(j) 
} yield t) map f getOrElse false 

Ist das sinnvoll? Es ist sicherlich lesbar. Ist es langsam?

Verwandte Themen