interval-iterator.ts 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { Iterator } from '../iterator';
  7. import { OrderedSet, Interval, Segmentation } from '../int';
  8. /** Emits a segment of length one for each element in the interval that is also in the set */
  9. export class IntervalIterator<I extends number = number> implements Iterator<Segmentation.Segment<I>> {
  10. private value: Segmentation.Segment<I> = { index: 0 as I, start: 0, end: 0 }
  11. private curIndex = 0
  12. private maxIndex = 0
  13. hasNext: boolean = false;
  14. updateValue() {
  15. this.value.index = this.curIndex as I;
  16. this.value.start = OrderedSet.findPredecessorIndex(this.set, Interval.getAt(this.interval, this.curIndex));
  17. this.value.end = this.value.start + 1;
  18. }
  19. move() {
  20. if (this.hasNext) {
  21. this.updateValue();
  22. while (this.curIndex <= this.maxIndex) {
  23. ++this.curIndex;
  24. if (OrderedSet.has(this.set, this.curIndex)) break;
  25. }
  26. this.hasNext = this.curIndex <= this.maxIndex;
  27. }
  28. return this.value;
  29. }
  30. constructor(private interval: Interval<I>, private set: OrderedSet<I>) {
  31. if (Interval.size(interval)) {
  32. this.curIndex = Interval.findPredecessorIndex(interval, OrderedSet.min(set));
  33. this.maxIndex = Interval.findPredecessorIndex(interval, OrderedSet.max(set));
  34. }
  35. this.hasNext = OrderedSet.areIntersecting(this.interval, this.set);
  36. }
  37. }