Skip to content

Instantly share code, notes, and snippets.

@oisdk
Last active August 29, 2015 14:24
Show Gist options
  • Save oisdk/4b68873a7da99d112158 to your computer and use it in GitHub Desktop.
Save oisdk/4b68873a7da99d112158 to your computer and use it in GitHub Desktop.
public class SelectGenerator<T> : GeneratorType {
private var head: T?
private var tail: [T] = []
private var first: Bool = true
private var gen: SelectGenerator<T>?
public func next() -> (T, [T])? {
return first ? {
first = false
gen = SelectGenerator(g: tail.generate())
return (head!, tail)
}() : gen?.next().map { ($0, [head!] + $1) }
}
private init<G : GeneratorType where G.Element == T>(var g: G) {
if let h = g.next() {
self.head = h
self.tail = Array(GeneratorSequence(g))
} else {
self.first = false
}
}
}
public func select<G : GeneratorType>(gen: G) -> SelectGenerator<G.Element> {
return SelectGenerator(g: gen)
}
var g = select([1, 2, 3, 4].generate())
g.next() // (1, [2, 3, 4])
g.next() // (2, [1, 3, 4])
g.next() // (3, [1, 2, 4])
g.next() // (4, [1, 2, 3])
g.next() // nil
var uG = [1].generate()
uG.next() // uG is now empty.
var eG = select(uG) // previously would have crashed, with a force-unwrap. Now safe.
eG.next() // nil
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment