Created
June 18, 2015 17:40
-
-
Save oisdk/79898d78bdff91018c1a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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