For ... and the state of the iterator

Consider this python code

it = iter([1, 2, 3, 4, 5])

for x in it:
    print x
    if x == 3:
        break

print '---'

for x in it:
    print x

it prints 1 2 3 --- 4 5because the iterator itremembers its state looped. When I do, it seems the same thing in JS, all I get is this 1 2 3 ---.

function* iter(a) {
    yield* a;
}

it = iter([1, 2, 3, 4, 5])

for (let x of it) {
    console.log(x)
    if (x === 3)
        break
}

console.log('---')

for (let x of it) {
    console.log(x)
}
Run codeHide result

What am I missing?

+6
source share
5 answers

Generator objects in JS are unfortunately not reused. Clearly indicated on MDN

Generators should not be reused, even if the for ... cycle sooner or later, for example, through the break keyword. After exiting the cycle, the generator is closed and tries to repeat it again. do not give any further results.

+6
source

, .

, .

.

function resume_iter(src) {
  const it = src[Symbol.iterator]();
  return {
    iter: function* iter() {
      while(true) {
        const next = it.next();
        if (next.done) break;
        yield next.value;
      }
    }
  }
}

const it = resume_iter([1,2,3,4,5]);

for (let x of it.iter()) {
    console.log(x)
    if (x === 3)
        break
}

console.log('---')

for (let x of it.iter()) {
    console.log(x)
}



console.log("");
console.log("How about travesing the DOM");

const it2 = resume_iter(document.querySelectorAll("*"));

for (const x of it2.iter()) {
  console.log(x.tagName);
  //stop at first Script tag.
  if (x.tagName === "SCRIPT") break;
}

console.log("===");

for (const x of it2.iter()) {
  console.log(x.tagName);
}
Hide result
+3

, for..of, . , , , .

- :

function* iter(a) {
  yield* a;
}

let values = [1, 2, 3, 4, 5];
let it = iter(values)

for (let i = 0, n = values.length; i < n; i++) {
  let x = it.next().value
  console.log(x)
  if (x === 3)
    break
}

console.log('---')

for (let x of it) {
  console.log(x)
}
Hide result

while, values:

function* iter(a) {
  yield* a;
}

let it = iter([1, 2, 3, 4, 5]),
  contin = true

while (contin && (x = it.next().value)) {
  console.log(x)
  if (x === 3)
    contin = false
}

console.log('---')

for (let x of it) {
  console.log(x)
}
Hide result

( while) , x. , x , undefined . , , . - if(x===undefined)contin=false , .

+1

Andrey, , Python script, , , , , :

function* iter(a) {
  yield* a;
}

var broken = 0;

iterate();
console.log('---');
iterate();

function iterate() {
  var it = iter([1, 2, 3, 4, 5]);
  for (let x of it) {
    if (x <= broken)
      continue;
    console.log(x);
    if (x === 3) {
      broken = x;
      break;
    }
  }
}
Hide result
0

, for..of , , ,

function iter(a) {
    let it = function* () {
        yield* a;
    }();

    return {
        * [Symbol.iterator]() {
            while (1) {
                let r = it.next();
                if (!r.done)
                    yield r.value;
                else
                    break;
            }
        }
    }
}


it = iter([1, 2, 3, 4, 5]);

for (let x of it) {
    console.log(x);
    if (x === 3)
        break;
}

console.log('---');

for (let x of it) {
    console.log(x);
}
Hide result
0

All Articles