Obviously if you google "lazy array in Swift," you'll find out the right way to do this, which uses NSPointerArray and whatever else. As you should.

But sometimes you want to make your own to see how far you can get in half an hour with generics. Here's my naive implementation.

import Foundation

private class WeakWrapperAnyObject> {
weak var thing: T?
init(_ thing:T) {
self.thing = thing
}
}

struct WeakArrayAnyObject> : Sequence {
private var array: [WeakWrapper<T>] = []
var count: Int { return objects.count }
init(_ objects: [T]) {
append(objects)
}
var objects: [T] {
get {
let retVal: [T?] = array.map { $0.thing != nil ? $0.thing : nil }
return retVal.flatMap { $0 }
}
}
mutating func append(_ object: T) {
array.append(WeakWrapper(object))
}
mutating func append(_ objects: [T]) {
array.append(contentsOf: objects.map { WeakWrapper($0) })
}
mutating func compress() {
array = array.filter{ $0.thing != nil }
}
// MARK: - Sequence Protocol methods
typealias Iterator = IndexingIterator<Array<T>>
func makeIterator() -> Iterator {
return objects.makeIterator()
}
}

let firstObject = NSString(string: "one")
var things = WeakArray([firstObject, NSString(string: "two"), NSString(string: "three")])
things.count
for thing in things {
print("Just one \(thing)")
}
things.compress()

Of course, I did have to look some stuff up, particularly to understand how easy Sequence was to implement (since I already have an array).