2

CODEPEN

Trying to wrap my head around generator and I just don't get it.

I have a simple non generator iterator class called KeyGen that I would like to rewrite using JS generators:

If this isn't what generators are suppose to do than please leave a comment and I'll close

class KeyGen {
  constructor(numOfKeys) {
    this.keys = new Array(numOfKeys).fill(0).map((i, index) => index);
    this.iteratorCount = 0;
  }

  keyIterator() {
    return {
      next: () => this.keys[this.iteratorCount++]
    }
  }
}

const keyGen = new KeyGen(4);

console.log(keyGen.keyIterator().next());
console.log(keyGen.keyIterator().next());
console.log(keyGen.keyIterator().next());
console.log(keyGen.keyIterator().next());

2 Answers 2

2

It's pretty straightforward, just declare the array and then yield each element:

function* gen(length) {
  const keys = Array.from({ length }, (_, i) => i);
  for (const key of keys) yield key;
}

const iter = gen(3);
console.log(iter.next().value);
console.log(iter.next().value);
console.log(iter.next().value);

Sign up to request clarification or add additional context in comments.

Comments

1

A generator would be a good fit here, but you should note that your original code is not the same as generator. For a generator, the next call should return an object with two keys, value and done.

To convert to a generator function, you just need to build the initial list to iterate over in the same way you do now, but then you can just use a normal for loop to yield each element one by one.

Example:

function* KeyGen(numOfKeys) {
    const keys = Array(numOfKeys)
      .fill(0)
      .map((i, index) => index);
      
    for (let key of keys) {
      yield key;
    }
}

const keyGen = KeyGen(4);

console.log(keyGen.next())
console.log(keyGen.next())
console.log(keyGen.next())
console.log(keyGen.next())
console.log(keyGen.next())

// For extra coolness, note that for/of loops are designed to work with generators:
for (let key of KeyGen(4)) {
    console.log(key)
}

2 Comments

if it was a method of a class the * goes behind the *methodName yeah?
Yes. The * will go before the method name. EG: class Foo { *bar() { yield 1 } }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.