Created
October 23, 2018 12:32
-
-
Save fewlinesofcode/885e6bedf6f2a45db832a5d509a4e8b7 to your computer and use it in GitHub Desktop.
IteratorAndSequence.swift
This file contains hidden or 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
//: Playground - noun: a place where people can play | |
import UIKit | |
/*: | |
## `Date` wrapping and convenience methods | |
*/ | |
let calendar = Calendar.current | |
extension Int { | |
public var days: DateComponents { | |
return calendarUnit(unit: .day) | |
} | |
private func calendarUnit(unit: Calendar.Component) -> DateComponents { | |
var dateComponents = DateComponents() | |
dateComponents.setValue(self, for: unit) | |
return dateComponents | |
} | |
} | |
extension Date { | |
private func valueForUnit(unit: Calendar.Component) -> Int { | |
return calendar.component(unit, from: self) | |
} | |
var weekday: Int { | |
return valueForUnit(unit: .weekday) | |
} | |
} | |
func + (date: Date, component: DateComponents) -> Date { | |
if let date = calendar.date(byAdding: component, to: date) { | |
return date | |
} | |
fatalError() | |
} | |
let date = Date() | |
let nextDay = date + 3.days | |
/*: | |
## Generators and sequences section | |
*/ | |
class DateGenerator: IteratorProtocol { | |
// We are using naive approach here | |
// It shouldn't be used in real project | |
var dayOffWeekday: Int = 1 // Sunday | |
var N: Int = 3 | |
private(set) var lessonsCount: Int | |
private(set) var startDate: Date | |
private var numIterations = 0 | |
init(_ start: Date, _ numLessons: Int) { | |
lessonsCount = numLessons | |
startDate = start | |
} | |
func next() -> Date? { | |
guard numIterations < lessonsCount else { | |
return nil | |
} | |
numIterations += 1 | |
var next = startDate + N.days | |
if next.weekday == dayOffWeekday { | |
next = next + 1.days | |
} | |
startDate = next | |
return next | |
} | |
} | |
let dg = DateGenerator(Date(), 10) | |
dg.N = 1 | |
dg.dayOffWeekday = 1 | |
while let date = dg.next() { | |
print(date) | |
} | |
while let date = dg.next() { // Exhausted | |
print(date) | |
} | |
class DateSequece: Sequence { | |
typealias Element = Date | |
typealias Iterator = DateGenerator | |
private var lessonsCount: Int | |
private var startDate: Date | |
init(_ start: Date, _ numLessons: Int){ | |
lessonsCount = numLessons | |
startDate = start | |
} | |
func makeIterator() -> Iterator { | |
return DateGenerator(startDate, lessonsCount) | |
} | |
} | |
let sequence = Array(DateSequece(Date(), 10)) | |
/*: | |
## `SequenceType` section | |
*/ | |
class SimpleDateSequece: Sequence { | |
typealias Element = Date | |
typealias Iterator = AnyIterator<Element> | |
var lessonsCount: Int | |
var startDate: Date | |
var daysStep: Int = 1 | |
private var numIterations = 0 | |
init(_ start: Date, _ numLessons: Int, step: Int){ | |
lessonsCount = numLessons | |
startDate = start | |
daysStep = step | |
} | |
func makeIterator() -> AnyIterator<Date> { | |
return AnyIterator({ () -> Date? in | |
guard self.numIterations < self.lessonsCount else { | |
return nil | |
} | |
self.numIterations += 1 | |
let next = self.startDate + self.daysStep.days | |
self.startDate = next | |
return next | |
}) | |
} | |
} | |
let simpleSequence = Array(SimpleDateSequece(Date(), 5, step: 4)) | |
/*: | |
## Infinite sequences section | |
*/ | |
class InfiniteDateGenerator: IteratorProtocol { | |
var startDate: Date | |
private var numIterations = 0 | |
init(_ start: Date) { | |
startDate = start | |
} | |
func next() -> Date? { | |
let next = startDate + 1.days | |
startDate = next | |
return next | |
} | |
} | |
class InfiniteDateSequece: Sequence { | |
typealias Element = Date | |
typealias Iterator = InfiniteDateGenerator | |
private var startDate: Date | |
init(_ start: Date){ | |
startDate = start | |
} | |
func makeIterator() -> InfiniteDateGenerator { | |
return InfiniteDateGenerator(startDate) | |
} | |
} | |
//let infiniteSequence = Array(InfiniteDateSequece(NSDate())) | |
let tenFirsElements = Array(InfiniteDateSequece(Date()).prefix(10)) | |
let mondayIndex = 2 | |
//let noMondaysSequence = Array(InfiniteDateSequece(NSDate()).filter({$0.weekday != mondayIndex}).prefix(10) ) // Infinite | |
let lazyNoMondaysSequence = Array(InfiniteDateSequece(Date()).lazy.filter({$0.weekday != mondayIndex}).prefix(10) ) // Finite |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment