Last active
August 29, 2015 14:25
-
-
Save kristopherjohnson/516b24ca19f6b9d247c3 to your computer and use it in GitHub Desktop.
Arrays that repeat their elements forever
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// 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