Skip to content

Instantly share code, notes, and snippets.

@airspeedswift
Created July 4, 2015 17:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save airspeedswift/08b0122228e614bf4cce to your computer and use it in GitHub Desktop.
Save airspeedswift/08b0122228e614bf4cce to your computer and use it in GitHub Desktop.
LazilyFlattenedCollection
struct LazilyFlattenedRandomAccessCollection<C: CollectionType where C.Index: RandomAccessIndexType> {
let collections: [C]
var count: Int {
return collections.reduce(0) { (total: Int, next: C) -> Int in
total + numericCast(next.count)
}
}
var startIndex: Int { return 0 }
var endIndex: Int { return count }
// obviously this is horribly inefficient for large numbers of
// collections, but could be sped up by caching the counts
// to locate the right subcollection in O(1) time
subscript(idx: Int) -> C.Generator.Element {
var previousCounts = 0
guard let collectionIdx = collections.indexOf({
let thisCount = numericCast($0.count) as Int
if previousCounts + thisCount < idx {
previousCounts += thisCount
return false
}
else {
return true
}
})
else { fatalError("Index out of bounds") }
let c = collections[collectionIdx]
return c[c.startIndex.advancedBy(numericCast(idx - previousCounts))]
}
}
let a = [
Array("abcdefghijklmnopqrstuvwxyz".characters),
Array("0123456789".characters),
]
let l = LazilyFlattenedRandomAccessCollection(collections: a)
l[28] // "2"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment