Skip to content

Instantly share code, notes, and snippets.

@kristopherjohnson
Last active August 29, 2015 14:25
Show Gist options
  • Save kristopherjohnson/516b24ca19f6b9d247c3 to your computer and use it in GitHub Desktop.
Save kristopherjohnson/516b24ca19f6b9d247c3 to your computer and use it in GitHub Desktop.
Arrays that repeat their elements forever
/// Sequence generator for an array that repeats the array elements forever
struct ArrayRecyclingGenerator<Element>: GeneratorType {
private let array: [Element]
private var nextIndex: Int
init(array: [Element], nextIndex: Int = 0) {
self.array = array
self.nextIndex = nextIndex
}
mutating func next() -> Element? {
if nextIndex >= array.count {
nextIndex = nextIndex % array.count
}
return array[nextIndex++]
}
}
/// For an array, support subscripting and sequence where elements repeat
struct ArrayRecycler<Element>: ArrayLiteralConvertible, SequenceType {
let array: [Element]
init(arrayLiteral elements: Element...) {
array = Array(elements)
}
init<S : SequenceType where S.Generator.Element == Element>(_ s: S) {
array = Array(s)
}
init(count: Int, repeatedValue: Element) {
array = Array(count: count, repeatedValue: repeatedValue)
}
subscript (index: Int) -> Element {
return array[index % array.count]
}
func generate() -> ArrayRecyclingGenerator<Element> {
return ArrayRecyclingGenerator(array: array)
}
}
// Create a recycler for an array of four elements
let a: ArrayRecycler<Int> = [0, 1, 2, 3]
// Elements repeat when index is larger than the actual array size
a[0] // 0
a[1] // 1
a[2] // 2
a[3] // 3
a[4] // 0
a[5] // 1
a[6] // 2
a[7] // 3
a[8] // 0
// Can read as an infinite sequence (but we only get the first 16 elements)
var limit = 16
for elem in a {
print(elem, appendNewline: false) // "0123012301230123"
if --limit == 0 { break }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment