использовать элементы из итератора scala - PullRequest
12 голосов
/ 01 октября 2011

Я запутался в поведении метода take в признаке Iterator. Кажется, что он не потребляет предметы. Вот пример:

scala> Iterator(1,2,3)
res0: Iterator[Int] = non-empty iterator

scala> res0 take 2 toArray
res1: Array[Int] = Array(1, 2)

scala> res0.next
res2: Int = 1

Очевидно, что шаг 2 потребляет два элемента, но на этапе 3 Iterator по-прежнему является первым элементом. Глядя на реализацию, я не вижу никакого вида копирования или буферизации, просто новый Iterator, который делегирует базовый. Как это могло быть возможно? Как мне реально потреблять n предметов?

Ответы [ 3 ]

11 голосов
/ 01 октября 2011

Рассматриваемый итератор определен в IndexedSeqLike#Elements ( source ). заявка была недавно подана о несовместимом поведении take в различных реализациях итераторов.

Чтобы реально использовать N элементов, вызовите Iterator#next N раз.

Возможно, вы захотите использовать Stream, который является ленивым (например, Iterator), но также неизменным (в отличие от Iterator).

scala> val s = Stream(1, 2, 3)
s: scala.collection.immutable.Stream[Int] = Stream(1, ?)

scala> s.take(2).toList
res43: List[Int] = List(1, 2)

scala> s.take(2).toList
res44: List[Int] = List(1, 2)

scala> s.drop(2).toList
res45: List[Int] = List(3)

scala> {val (s1, s2) = s.splitAt(2); (s1.toList, s2.toList)}
res46: (List[Int], List[Int]) = (List(1, 2),List(3))
2 голосов
/ 02 октября 2011

Спасибо, ребята.

Это мое решение потреблять кучу предметов из Iterator:

  implicit def consumable(i: Iterator[_]) = new {
    def next(n: Int) = {
      (for (_ <- 1 to n) yield i.next()).iterator
    }
    def skip(n: Int) {
      (1 to n).foreach(_ => i.next())
    }
  }

любые комментарии будут приветствоваться.

1 голос
/ 01 октября 2011

Вы хотите потреблять предметы, drop их.Обратите внимание, что большинство методов, вызываемых Iterator, делают его Iterator бесполезным для дальнейшего использования - бесполезным в том смысле, что поведение не определено и может быть изменено.

...