javascriptiterator

How do you reset an iterator?


I'm learning about iterators/generators, and am wondering if there is a way to make the iterator reset itself? Like when after you call the last .next() is there a way to make it restart?

function nextName() {
   const current = names.next().value
  const output = document.querySelector("output")
  if (current) { 
      output.innerText = current.name
    } 
    else { 
     // code to reset it! currently I'm just displaying text
     output.innerText = 'Nothing left'
     }
}

function nameIterator(names) {
  let nextIndex = 0;
  return {
    next: function() {
      return nextIndex < names.length ? 
        { value: names[nextIndex++], done: false } :
        { done: true }
     }
  }
}

Here's a codepen to be more clear: https://codepen.io/sammiepls/pen/romyKL?editors=1010

So when you click the button, it calls my iterator which will display the names in my names array one by one each time you click. How can I make it reset on the last click so it goes back to the first name?

So the display would be like:

Bob

Peter

Sally

Bob // get Bob again

In the codepen I have also written the iterator using a generator, is there anyway for that to also be able to reset back to the first one after yielding through the array?


Solution

  • The general answer is that you can't reset an iterable in JS. This is, as far as I know, by-design, although I'm not privy to the decision-making process that was used to reach that conclusion.

    In your specific case however, you don't want to necessarily reset the iterator, you want to cycle through the array. In that case, you can use the modulo operator as follows:

    function nameIterator(names) {
      let nextIndex = 0;
      return {
        next: function() {
          nextIndex = (nextIndex + 1) % names.length;
          return { value: names[nextIndex], done: false };
        }
      }
    }