gpt4 book ai didi

scala - 通过查找标记值(在 Scala 中)对可迭代对象中的项目进行分组

转载 作者:行者123 更新时间:2023-12-04 14:35:41 24 4
gpt4 key购买 nike

我有一个非常大的文件中的行的迭代器,随着我的移动需要将其分组。我知道每个组在哪里结束,因为每个组的最后一行都有一个哨兵值。所以基本上我想编写一个函数,它接受一个迭代器和一个哨兵值,并返回一个由哨兵值终止的组的迭代器。就像是:

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, .))

请注意,我希望在每个组的末尾包含哨兵项目。这是我目前的解决方案:
def groups[T](iter: Iterator[T], sentinel: T) = new Iterator[Seq[T]] {                   
def hasNext = iter.hasNext
def next = iter.takeWhile(_ != sentinel).toList ++ List(sentinel)
}

我认为这会起作用,我想这很好,但是每次都必须重新添加哨兵会给我一种代码气味。有一个更好的方法吗?

最佳答案

比你的可读性差,但当最后一组没有终止哨兵值时更“正确”:

def groups[T](iter: Iterator[T], sentinel: T) = new Iterator[Seq[T]] {
def hasNext = iter.hasNext
def next: Seq[T] = {
val builder = scala.collection.mutable.ListBuffer[T]()
while (iter.hasNext) {
val x = iter.next
builder.append(x)
if (x == sentinel) return builder
}
builder
}
}

或者,递归地:
  def groups[T](iter: Iterator[T], sentinel: T) = new Iterator[Seq[T]] {
def hasNext = iter.hasNext
def next: Seq[T] = {
@scala.annotation.tailrec
def build(accumulator: ListBuffer[T]): Seq[T] = {
val v = iter.next
accumulator.append(v)
if (v == sentinel || !iter.hasNext) => accumulator
else build(accumulator)
}
build(new ListBuffer[T]())
}
}

关于scala - 通过查找标记值(在 Scala 中)对可迭代对象中的项目进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3231160/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com