Javascript create an iterator

Date: 2020-01-29
obj[Symbol.iterator] // a function that returns an Iterator 'instance'
obj[Symbol.iterator]() // Iterator
// an iterator is an object with an method: 
// .next() that returns { value: any,  done: boolean}
{ next: () => ({ value: 1, done: false}) }

// generators return an Iterator
function* range(from, to) {
  let i = from;
  while (i <= to) {
    yield i;
    i++;
  }
}

const a = { [Symbol.iterator]: () => range(0, 10) };
for (const item of a) console.log(item);

(()=>{
function* iterator(iterable) {
	for(const item of iterable)
		yield item;
}
const x = ['a', 'b'];
const y = ['c', 'd'];
console.log(x.concat(y));
const b = { [Symbol.iterator]: () => iterator(x.concat(y)) };
for (const item of b) console.log(item);
})();

https://codeburst.io/a-simple-guide-to-es6-iterators-in-javascript-with-examples-189d052c3d8e

const myFavouriteAuthors = {
  allAuthors: {
    fiction: [
      'Agatha Christie', 
      'J. K. Rowling',
      'Dr. Seuss'
    ],
    scienceFiction: [
      'Neal Stephenson',
      'Arthur Clarke',
      'Isaac Asimov', 
      'Robert Heinlein'
    ],
    fantasy: [
      'J. R. R. Tolkien',
      'J. K. Rowling',
      'Terry Pratchett'
    ],
  },
  [Symbol.iterator]() {
    // Get all the authors in an array
    const genres = Object.values(this.allAuthors);
    
    // Store the current genre and author index
    let currentAuthorIndex = 0;
    let currentGenreIndex = 0;
    
    return {
      // Implementation of next()
      next() {
        // authors according to current genre index
        const authors = genres[currentGenreIndex];
        
        // doNotHaveMoreAuthors is true when the authors array is exhausted.
        // That is, all items are consumed.
        const doNothaveMoreAuthors = !(currentAuthorIndex < authors.length);
        if (doNothaveMoreAuthors) {
          // When that happens, we move the genre index to the next genre
          currentGenreIndex++;
          // and reset the author index to 0 again to get new set of authors
          currentAuthorIndex = 0;
        }
        
        // if all genres are over, then we need tell the iterator that we 
        // can not give more values.
        const doNotHaveMoreGenres = !(currentGenreIndex < genres.length);
        if (doNotHaveMoreGenres) {
          // Hence, we return done as true.
          return {
            value: undefined,
            done: true
          };
        }
        
        // if everything is correct, return the author from the 
        // current genre and incerement the currentAuthorindex
        // so next time, the next author can be returned.
        return {
          value: genres[currentGenreIndex][currentAuthorIndex++],
          done: false
        }
      }
    };
  }
};

for (const author of myFavouriteAuthors) {
  console.log(author);
}

console.log(...myFavouriteAuthors)
32920cookie-checkJavascript create an iterator