Skip to content

Instantly share code, notes, and snippets.

@michaeleisel
Last active March 14, 2019 18:36
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 michaeleisel/28742db8f36c55c4b12d4ac6a8a63b91 to your computer and use it in GitHub Desktop.
Save michaeleisel/28742db8f36c55c4b12d4ac6a8a63b91 to your computer and use it in GitHub Desktop.
struct ReductionsSequence<Base: Sequence, T>: Sequence, IteratorProtocol {
typealias Element = T
private var iterator: AnyIterator<Base.Element>
private var current: T
private let reducer: (T, Base.Element) -> T
init(sequence: Base, initialValue: T, reducer: @escaping (T, Base.Element) -> T) {
iterator = AnyIterator(sequence.makeIterator())
self.reducer = reducer
current = initialValue
}
mutating func next() -> ReductionsSequence<Base, T>.Element? {
guard let next = iterator.next() else {
return nil
}
let previous = current
current = reducer(current, next)
return previous
}
}
extension Array {
func reductions<T>(initialValue: T, _ reduce: @escaping (T, Element) -> T) -> AnySequence<T> {
return AnySequence(ReductionsSequence(sequence: self, initialValue: T, reducer: reduce))
// Cannot convert value of type '(T, Array<Element>.Element) -> T' (aka '(T, Element) -> T') to expected argument type '(_, _) -> _'
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment