2013-11-04 26 views
7

Mam wektor wektorów, do których uzyskuję dostęp w celu zastosowania funkcji boolowskiej. tjCzy istnieje prosty sposób domyślnego przekroczenia granic w zagnieżdżonych Seqach w Scali?

Vector[Vector[T]] gdzie mam zamiar wykonać coś w rodzaju f(myVector(i)(j)) gdzie F jest typu T => Boolean.

Ale to nie sprawdza granic i nie mogę dostać czegoś naprawdę eleganckiego.

mogę używać applyOrElse: myVector.applyOrElse(i, (_:Int) => Vector.empty).applyOrElse (j, (_:Int) => defaultT)

gdzie f(defaultT) wróci false Ale Chciałabym po prostu ustawić domyślną wartość zamiast funkcji.

mogę używać windy, aby dać mi Option, ale nie komponować dobrze na drugim poziomie: myVector.lift(i) map (_.lift(j) map f getOrElse false) getOrElse false

Który działa, ale nadal jest bardzo trudne do odczytania.

A jeszcze norma if/else bloki:

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

prostu wydaje się jak coś, co powinno być w stanie rozłożyć łatwiejsze niż to, co można osiągnąć. A jeśli dodaję trzecią warstwę, robi się jeszcze brzydsza.

Czy są jeszcze inne opcje?

Wsparcie to jest adaptacją progfun oczywiście Coursera za

Odpowiedz

2

Weźmy następujący kod z pytaniem:

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

To może być przepisana następująco:

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

Albo przed fold został wprowadzony w Scala 2.10:

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

Kluczową ideą jest odroczenie rozpakowania (lub mapowania) na Option jako jak to możliwe. Takie podejście uogólni się całkowicie na więcej niż dwa wymiary.

Jest to dość blisko równoważne for -comprehension w swojej odpowiedzi (zakładając, że ma obejmować lift tam), ale gdy trzeba owinąć zrozumieniem w nawiasach osobiście wydają się znaleźć w wersji Odcukrzony jaśniejsze.

+0

Fantastyczna - próbowałem utrzymać Opcję, ale zapomniałem o podstawach rozumienia listy. Dzięki. – Stephen

+0

2.10 krótsza wersja: 'myVector.lift (i) .flatMap (_. Lift (j)). Istnieje (f)' – lpandzic

0

mam zorientowali, że coś wydaje się elegancki, nawet jeśli wydaje się być trochę przesada:

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

Czy to rozsądne? Jest z pewnością czytelny. Czy to jest wolne?

Powiązane problemy