Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save nubbel/884261addc989623b8fd to your computer and use it in GitHub Desktop.
Save nubbel/884261addc989623b8fd to your computer and use it in GitHub Desktop.
struct TakeSequenceView<Base : SequenceType> : SequenceType {
let base: Base
let n: Int
init(_ base: Base, n: Int) {
self.base = base
self.n = n
}
func generate() -> GeneratorOf<Base.Generator.Element> {
var i = 0
var g = base.generate()
return GeneratorOf {
i++ < self.n ? g.next() : nil
}
}
}
struct TakeWhileSequenceView<Base : SequenceType> : SequenceType {
let base: Base
let predicate: Base.Generator.Element -> Bool
init(_ base: Base, predicate: Base.Generator.Element -> Bool) {
self.base = base
self.predicate = predicate
}
func generate() -> GeneratorOf<Base.Generator.Element> {
var g = base.generate()
return GeneratorOf {
if let x = g.next() {
if self.predicate(x) {
return x
}
}
return nil
}
}
}
extension LazySequence {
func take(n: Int) -> LazySequence<TakeSequenceView<LazySequence>> {
return lazy(TakeSequenceView(self, n: n))
}
func takeWhile(predicate: S.Generator.Element -> Bool) -> LazySequence<TakeWhileSequenceView<LazySequence>> {
return lazy(TakeWhileSequenceView(self, predicate))
}
}
extension LazyForwardCollection {
func take(n: Int) -> LazySequence<TakeSequenceView<LazyForwardCollection>> {
return lazy(TakeSequenceView(self, n: n))
}
func takeWhile(predicate: S.Generator.Element -> Bool) -> LazySequence<TakeWhileSequenceView<LazyForwardCollection>> {
return lazy(TakeWhileSequenceView(self, predicate))
}
}
extension LazyBidirectionalCollection {
func take(n: Int) -> LazySequence<TakeSequenceView<LazyBidirectionalCollection>> {
return lazy(TakeSequenceView(self, n: n))
}
func takeWhile(predicate: S.Generator.Element -> Bool) -> LazySequence<TakeWhileSequenceView<LazyBidirectionalCollection>> {
return lazy(TakeWhileSequenceView(self, predicate))
}
}
extension LazyRandomAccessCollection {
func take(n: Int) -> LazySequence<TakeSequenceView<LazyRandomAccessCollection>> {
return lazy(TakeSequenceView(self, n: n))
}
func takeWhile(predicate: S.Generator.Element -> Bool) -> LazySequence<TakeWhileSequenceView<LazyRandomAccessCollection>> {
return lazy(TakeWhileSequenceView(self, predicate))
}
}
lazy(1...10).take(3).array // [1, 2, 3]
var prev = 0
var lstw = lazy([1, 2, 3, 2, 1]).takeWhile { (x: Int) in
if (x < prev) {
return false
}
prev = x
return true
}.array // => [1, 2, 3]
@tokafish
Copy link

Just to help the next person who looks at this, unfortunately prefix isn't lazy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment