2011-09-03 72 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个分隔符的列表将堆栈 –