Skip to content

Instantly share code, notes, and snippets.

@oisdk
Created June 18, 2015 17:40
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 oisdk/79898d78bdff91018c1a to your computer and use it in GitHub Desktop.
Save oisdk/79898d78bdff91018c1a to your computer and use it in GitHub Desktop.
public struct DropSeq<S : SequenceType> : LazySequenceType {
typealias Generator = S.Generator
private let seq: S
private let n: Int
public func generate() -> Generator {
var g = seq.generate()
for _ in 0..<n { g.next() }
return g
}
}
public extension LazySequenceType {
func drop(n: Int) -> DropSeq<Self> {
return DropSeq(seq: self, n: n)
}
}
public struct TakeSeq<S : SequenceType> : LazySequenceType {
typealias Generator = TakeGen<S.Generator>
private let seq: S
private let n: Int
public func generate() -> Generator {
return TakeGen(g: seq.generate(), n: n)
}
}
public struct TakeGen<G : GeneratorType> : GeneratorType {
typealias Element = G.Element
private var g: G
private var n: Int
mutating public func next() -> Element? {
return --n < 0 ? nil : g.next()
}
private init(g: G, n: Int) {
self.g = g
self.n = n
}
}
public extension LazySequenceType {
func take(n: Int) -> TakeSeq<Self> {
return TakeSeq(seq: self, n: n)
}
}
public struct WhileGen<G : GeneratorType> : GeneratorType {
typealias Element = G.Element
private var g: G
private let condition : G.Element -> Bool
mutating public func next() -> Element? {
return g.next().flatMap {
condition($0) ? $0 : nil
}
}
}
public struct WhileSeq<S : SequenceType> : LazySequenceType {
typealias Generator = WhileGen<S.Generator>
private let seq: S
private let condition: S.Generator.Element -> Bool
public func generate() -> Generator {
return WhileGen(g: seq.generate(), condition: condition)
}
}
public extension LazySequenceType {
func takeWhile(condition: Generator.Element -> Bool) -> WhileSeq<Self> {
return WhileSeq(seq: self, condition: condition)
}
func takeUntil(condition: Generator.Element -> Bool) -> WhileSeq<Self> {
return WhileSeq(seq: self) {!condition($0)}
}
}
public struct DropWhileGen<G : GeneratorType> : GeneratorType {
typealias Element = G.Element
private let predicate: Element -> Bool
private var nG: G!
private var oG: G
init(g: G, predicate: Element -> Bool) {
self.nG = nil
self.oG = g
self.predicate = predicate
}
public mutating func next() -> Element? {
guard nG == nil else { return nG.next() }
while let next = oG.next() {
if !predicate(next) {
nG = oG
return next
}
}
return nil
}
}
public struct DropWhileSeq<S : SequenceType> : LazySequenceType {
typealias Generator = DropWhileGen<S.Generator>
private let predicate: Generator.Element -> Bool
private let seq: S
public func generate() -> Generator {
return DropWhileGen(g: seq.generate(), predicate: predicate)
}
}
public extension LazySequenceType {
func dropWhile(predicate: Generator.Element -> Bool) -> DropWhileSeq<Self> {
return DropWhileSeq(predicate: predicate, seq: self)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment