Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • 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]
@fabb
Copy link

fabb commented Aug 30, 2016

in swift 2 there is prefix which does the same as take. in swift 3 there will be prefix(while:) which does the same as takeWhile

@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