本文介绍了通过查找sentinel值(在scala中)对可迭代项目进行分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个来自非常大的文件的行的迭代器,当我移动时需要将它们放入组中。我知道每个组的结束位置,因为每个组的最后一行都有一个标记值。所以基本上我想编写一个带有迭代器和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中)对可迭代项目进行分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-23 02:32