import MathUtil from "./MathUtil"; export default class CircularIterator implements Iterator { private static readonly DEFAULT_INCREMENT_AMOUNT: number = 1; private i: number; constructor(private values: T[], startingIndex: number) { this.i = startingIndex - this.getIncrementAmount(); } public static of(values: T[], startingIndex: number = 0): CircularIterator { return new CircularIterator(values, startingIndex); } public reverse(): CircularIterator { const amount: number = this.getIncrementAmount(); const it: CircularIterator = new CircularIterator(this.values, this.i + this.getIncrementAmount()); it.getIncrementAmount = () => -amount; return it; } public [Symbol.iterator](): Iterator { return this; } public getValues(): T[] { return this.values; } public getCycleLength(): number { return this.values.length; } protected getIncrementAmount(): number { return CircularIterator.DEFAULT_INCREMENT_AMOUNT; } protected increment(): void { this.i = MathUtil.floorMod(this.i + this.getIncrementAmount(), this.getCycleLength()); } public getCurrentValue(): T { return this.getValues()[this.i]; } public next(): IteratorResult { this.increment(); return { value: this.getCurrentValue(), done: false }; } }