2011-09-03 44 views
11

在一個文本文件,我在表單數據的每個元素分裂出一個列表在滿足謂詞(斯卡拉)

val input = io.Source.fromFile("filename.txt").getLines().toList 

我要下破列表分爲子列表開始1)2)

我想出:

val subLists = 
    input.foldRight(List(List[String]())) { 
    (x, acc) => 
     if (x.matches("""[0-9]+\)""")) List() :: (x :: acc.head) :: acc.tail 
     else (x :: acc.head) :: acc.tail 
    }.tail 

這可以實現更簡單嗎?如果有一種內置方法可以在滿足謂詞的每個元素(提示,提示,庫設計器:)上拆分集合,那麼真的很好。

+1

看看這個問題,並接受的答案得到的結果根本。 com/questions/6800737/how-to-group-a-variable-length-repeating-sequence-in-scala – mpilquist

+0

在這個答案中可能使用迭代器,但這種情況更復雜,因爲每個標題都不同, d需要第二個Iterator/List作爲標題,並且它不再優雅。遞歸似乎更清潔。 –

回答

24

foldRight帶有一個複雜的參數通常表明您不妨使用遞歸編寫此代碼,並在您處於自己的方法時將其分解爲自己的方法。這是我想出來的。首先,讓我們來概括 到一個通用的方法,groupPrefix:HTTP://計算器

/** Returns shortest possible list of lists xss such that 
    * - xss.flatten == xs 
    * - No sublist in xss contains an element matching p in its tail 
    */ 
def groupPrefix[T](xs: List[T])(p: T => Boolean): List[List[T]] = xs match { 
    case List() => List() 
    case x :: xs1 => 
    val (ys, zs) = xs1 span (!p(_)) 
    (x :: ys) :: groupPrefix(zs)(p) 
} 

現在,您可以通過調用

groupPrefix(input)(_ matches """\d+\)""") 
+1

一個問題:這不適用於大量的組(堆棧溢出) –

+0

包含476k元素並帶有10000個分隔符的列表將堆棧 –