This page is no longer maintained — Please continue to the home page at www.scala-lang.org

why Iterator@takeDestructive?

1 reply
odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.

While trying to document Iterator (what a chore!) I stumbled upon this.

/** Since I cannot reliably get take(n) to influence the original
* iterator (it seems to depend on some ordering issue I don't
* understand) this method takes the way one might expect, leaving
* the original iterator with 'size' fewer elements.
*/
private def takeDestructively(size: Int): Seq[A] = {
val buf = new ArrayBuffer[A]
var i = 0
while (self.hasNext && i < size) {
buf += self.next
i += 1
}
buf
}

What's the deal here? Why not just do

it.take(n).toSeq

?

Cheers

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: why Iterator@takeDestructive?

On Tue, Dec 15, 2009 at 03:30:58PM +0100, martin odersky wrote:
> /** Since I cannot reliably get take(n) to influence the original
> * iterator (it seems to depend on some ordering issue I don't
> * understand) this method takes the way one might expect, leaving
> * the original iterator with 'size' fewer elements.
> */
> private def takeDestructively(size: Int): Seq[A] = {
> val buf = new ArrayBuffer[A]
> var i = 0
> while (self.hasNext && i < size) {
> buf += self.next
> i += 1
> }
> buf
> }
>
> What's the deal here? Why not just do
>
> it.take(n).toSeq

As implied by the comment, because take (at least at the time that I
wrote it) left the original iterator in an undefined state; only the one
returned by take was safely what you want. The purpose to which that is
being put (grouped) needed a way to take n elements and leave all the
rest behind.

I never pinned down why take wasn't working, but until I wrote that
function that way I was getting wrong answers.

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland