Source: util/iterable.js

/**
 * Utility class allowing to iterate a collection.
 *
 * Note: This should be used with immutable collections, e.g no add or remove
 * operations should be performed while iterating.
 *
 * @class
 * @author Mihail Radkov
 * @author Svilen Velikov
 */
class Iterable {
  /**
   * Constructs new iterable for the provided collection.
   *
   * @param {Object[]} iterable the collection to iterate
   */
  constructor(iterable) {
    this.iterable = iterable;
    this.index = 0;
    this.size = iterable.length;
  }

  /**
   * Returns if there are elements left to be iterated from the collection.
   *
   * Use this method before calling {@link next()} to avoid out of bounds error.
   *
   * @return {boolean} <code>true</code> if there is at least single element
   *                    left to iterate or <code>false</code> otherwise
   */
  hasNext() {
    return this.index < this.size;
  }

  /**
   * Returns the next object from the iterable collection.
   *
   * Before invoking this method, check if there are elements to iterate by
   * using {@link hasNext()} because if there are no objects left to iterate,
   * the function will blow with an error.
   *
   * @return {Object} the next iterated object from the collection
   * @throws {Error} if there are no more elements to be iterated
   */
  next() {
    if (!this.hasNext()) {
      throw new Error('There are no elements left to iterate!');
    }
    return this.iterable[this.index++];
  }

  /**
   * Resets the iterable to begin from the start as if it was just constructed.
   *
   * @return {Iterable} the current iterable for method chaining.
   */
  reset() {
    this.index = 0;
    return this;
  }
}

module.exports = Iterable;