2014-11-06 22 views
6

Jaki jest idiomatyczne sposób stosowania funkcji A => Try[B] na List[A] i powrócić bądź pierwszy wynik udany Some[B] (to zwarcie) lub jeśli wszystko zawiedzie, zwraca NoneScala: Spróbuj do pierwszego sukcesu na liście

Chcę zrobić coś takiego:

val inputs: List[String] = _ 

def foo[A, B](input: A): Try[B] = _ 

def main = { 
    for { 
    input <- inputs 
    } foo(input) match { 
    case Failure(_) => // continue 
    case Success(x) => return Some(x) //return the first success 
    } 
    return None // everything failed 
} 

Odpowiedz

7

Można zrobić to samo przy użyciu collectFirst w jeden mniej kroku:

inputs.iterator.map(foo).collectFirst { case Success(x) => x } 
+0

Powiązane pytanie. Co jeśli chciałbym albo najpierw "Sukces [A]", albo ostatnią "awarię"? – pathikrit

+0

@wrick: 'val tmp = inputs.toStream.map (foo); tmp.find (_. isSuccess) orElse tmp.lastOption' – senia

5

chcesz to:

inputs 
    .iterator // or view (anything lazy works) 
    .map(foo) 
    .find(_.isSuccess) 
    .map(_.get) 

zwraca Option[B].

+0

Nie, chcę go do „zwarcia” czyli nie oceniać po pierwszym sukcesie. 'foo' w moim przypadku jest kosztowne i powolne, a moja lista wejść jest duża. – pathikrit

+0

Do tego służy '.iterator'. Dlatego też powiedziałem, że leniwy działa. – Nate

Powiązane problemy