Repeating sequence

less than 1 minute read

Today I had the need to generate an infinite repeating sequence from a fixed ordered collection of elements. That is, from the items a, b, c, I needed an infinite sequence like a, b, c, a, b, c, a, b, c, ....

I though maybe I’d share it the off-chance that someone might need one:

public struct RepeatingSequence<T: Collection>: Sequence {
    private let base: T
    public init(baseCollection: T) {
        self.base = baseCollection
    }
    public func makeIterator() -> AnyIterator<T.Element> {
        var i = base.startIndex
        return AnyIterator({ [base] () -> T.Element in
            defer {
                i = (base.index(after: i) == base.endIndex)
                    ? base.startIndex : base.index(after: i)
            }
            return base[i]
        })
    }
}

extension Collection {
    public func repeated() -> RepeatingSequence<Self> {
        return RepeatingSequence(baseCollection: self)
    }
}

You can use it like any sequence, but remember to limit it before you traverse the entire sequence:

["a", "b", "c"].repeated().prefix(10)
// "a", "b", "c", "a", "b", "c", "a", "b", "c", "a"
["a", "b", "c"].reversed().repeated().dropFirst(5).prefix(2)
// "a", "c"

Tags:

Updated:

Leave a Comment