问题描述
我有一个来自非常大的文件的行的迭代器,当我移动时需要将它们放入组中。我知道每个组的结束位置,因为每个组的最后一行都有一个标记值。所以基本上我想编写一个带有迭代器和sentinel值的函数,并返回一组迭代器,每个迭代器都以sentinel值终止。类似于:
I have an iterator of lines from a very large file that need to be put in groups as I move along. I know where each group ends because there is a sentinel value on the last line of each group. So basically I want to write a function that takes an iterator and a sentinel value, and returns an iterator of groups each terminated by the sentinel value. Something like:
scala> groups("abc.defg.hi.jklmn.".iterator, '.')
res1: Iterator[Seq[Char]] = non-empty iterator
scala> groups("abc.defg.hi.jklmn.".iterator, '.').toList
res19: List[Seq[Char]] = List(List(a, b, c, .), List(d, e, f, g, .), List(h, i, .), List(j, k, l, m, n, .))
请注意,我希望在每个组的末尾包含哨兵项目。这是我目前的解决方案:
Note that I want the sentinel items included at the end of each of the groups. Here's my current solution:
def groups[T](iter: Iterator[T], sentinel: T) = new Iterator[Seq[T]] {
def hasNext = iter.hasNext
def next = iter.takeWhile(_ != sentinel).toList ++ List(sentinel)
}
我认为这会有效,我想这很好,但每次都要重新添加哨兵给我一个代码味道。有没有更好的方法呢?
I think this will work, and I guess it is fine, but having to re-add the sentinel every time gives me a code smell. Is there a better way to do this?
推荐答案
丑陋,但应该比你的解决方案更高效:
Ugly, but should be more performant than your solution:
def groups[T](iter: Iterator[T], sentinel: T) = new Iterator[Seq[T]] {
def hasNext = iter.hasNext
def next = iter.takeWhile{
var last = null.asInstanceOf[T]
c => { val temp = last; last = c; temp != sentinel}
}.toList
}
这篇关于通过查找sentinel值(在scala中)对可迭代项目进行分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!