2014-02-22 32 views
2

我試圖將應該返回單個項目的迭代器轉換爲等效選項。如何將scala Iterator [T]轉換爲Option [T]

我能做的最好的就是這個。我應該使用標準API的東西嗎?

def toUniqueOption[T](a: Iterator[T]): Option[T] = 
    if (a.size > 1) 
     throw new RuntimeException("The iterator should be emtpy or contain a single item but contained ${a.size} items.") 
    else if (a.size > 0) 
     Option(a.toList(0)) 
    else 
     Option.empty 
+0

這真的是一個壞主意,使用異常表達的邏輯。考慮一個類型'Either [String,Option [T]]'而不是。 –

+0

好的意思。我會嘗試使用Try [T],我發現它可以轉換爲選項[T] – raisercostin

回答

9

調用size是有風險的,因爲它不能保證有效或甚至停止。

如何:

def toUniqueOption[T](a: Iterator[T]): Option[T] = 
    a.take(2).toList match { 
    case Nil => None 
    case x :: Nil => Some(x) 
    case _ => throw new RuntimeException("Iterator size > 1") 
    } 
3

你能避免迭代使用hasNextnext整個序列:

def toUniqueOption[T](a: Iterator[T]): Option[T] = { 
    if(a.hasNext) { 
     val f = a.next() 
     if(a.hasNext) throw new RuntimeException("Iterator should contain at most one element") 
     Some(f) 
    } 
    else None 
} 
0

不完全是你問的是什麼,但爲什麼不使用這樣的:

def nextAsOption[T](i: Iterator[T]) : Option[T] = { 
    i.hasNext match { 
     case true => Some(i.next) 
     case false => None 
    } 
    } 

這只是爲您提供了一個迭代器「下一步」操作在返回一個選項而不是布爾值。當需要傳遞選項時非常方便。

+1

爲什麼不'if(i.hasNext)Some(i.next)else None'? – Derecho

+0

據我所知,它在效果和編譯器優化方面完全一樣。 – matanster

5

其實你可以使用標準的API:

a.toStream.headOption 

其中:迭代器[T]

相關問題