2013-11-20 37 views
1

的名單上:Lazify這個flatMap鑑於這種功能,我不能修改迭代器

def numbers(c: Char): Iterator[Int] = 
    if(Character.isDigit(c)) Iterator(Integer.parseInt(c.toString)) 
    else Iterator.empty 
// numbers: (c: Char)Iterator[Int] 

而這種輸入數據:

val data = List('a','b','c','1','d','&','*','x','9') 
// data: List[Char] = List(a, b, c, 1, d, &, *, x, 9) 

我怎樣才能讓這個功能慵懶,這樣的那data只處理到第一個出現的數字字符?

def firstNumber(data: List[Char]) :Int = data.flatMap(numbers).take(1) 

回答

2

只需調用數據.toStream應該這樣做:

firstNumber(data.toStream) 
2

一種可能性是使用Scala的集合視圖: http://www.scala-lang.org/docu/files/collections-api/collections_42.html

上調用集合.view允許你調用功能,如mapflatMap等的收集,而不會產生中間結果。

所以你的情況,你可以寫:

data.view.flatMap(numbers).take(1).force 

這將使一個List[Int]至多一個元素,只處理data的第一個號碼。

6
data.iterator.flatMap(numbers).take(1).toList 

不要使用流;你不需要存儲舊數據。不要使用視圖;他們沒有被仔細維護,無論如何是過度殺傷。

如果你想要一個Int,你需要一些默認行爲。根據那是什麼,你可能會選擇

data.iterator.flatMap(numbers).take(1).headOption.getOrElse(0) 

或類似

{ 
    val ns = data.iterator.flatMap(numbers) 
    if (ns.hasNext) ns.next 
    else throw new NoSuchElementException("Number missing") 
} 
+0

這看起來不錯,但我需要獲得'Int',而不是一個'列表[INT]' – noahlz