apple/swift-algorithms

Add new `FiniteCycle` type as the return type of `Collection.cycled(times:)`

timvermeulen opened this issue · 1 comments

cycled(times:) is currently implemented as follows:

extension Collection {
  public func cycled(times: Int) -> FlattenSequence<Repeated<Self>> {
    repeatElement(self, count: times).joined()
  }
}

This is suboptimal because FlattenSequence does not conform to RandomAccessCollection when the base collection does, even though the return value of cycled(times:) could! By implementing this method in terms of FlattenSequence, we are essentially throwing away the information that each inner collection is the same (and therefore has the same length).

Another way of repeating a collection a fixed number of times is by taking the product of it and an integer range:

let array = [10, 20, 30]
for (_, x) in product(0..<5, array) {
  print(x)  // 10, 20, 30, 10, 20, 30, 10, 20, 30, 10, 20, 30, 10, 20, 30
}

Unlike FlattenSequence, the Product2 collection does conditionally conform to RandomAccessCollection.

We should add a new FiniteCycle collection as the return type of product(times:) that wraps a Product2<Range<Int>, Base> value and conforms to RandomAccessCollection.

I'd like to take this one please! I might create a draft PR sometime soon to get your feedback / advice.