Skip to content

Instantly share code, notes, and snippets.

@Nirma
Last active March 24, 2016 02:57
Show Gist options
  • Save Nirma/58fb471d6e336906a443 to your computer and use it in GitHub Desktop.
Save Nirma/58fb471d6e336906a443 to your computer and use it in GitHub Desktop.
Hatena Blog Gist
//#Making Sequences work for you
//
// ไปŠๅ›žใฎใƒˆใƒ”ใƒƒใ‚ฏใฏSwift2.0ไปฅ้™ใฎ`SequenceType`ใจใ„ใ†ใƒ—ใƒญใƒˆใ‚ณใƒซใจใ€ใใฎๅ†…้ƒจ็š„ใชๅ‹•ใใซใคใ„ใฆ็ดนไป‹ใ—ใพใ™ใ€‚`class`ใ‚„`struct`ใ‚’`SequenceType`ใƒ—ใƒญใƒˆใ‚ณใƒซใซๆบ–ๆ‹ ใ•ใ›ใ‚‹ใจใ€`for in`ใƒซใƒผใƒ—ใ‚„`map`, `filter`ใชใฉใ‚’ไฝฟใˆใ‚‹ใ‚ˆใ†ใซใชใ‚Šใพใ™ใ€‚
//
//ใ•ใ‚ใ€ๅง‹ใ‚ใพใ—ใ‚‡ใ†๏ผ
struct Unique<T: Comparable> {
private var backingStore: [T] = []
var count: Int {
return backingStore.count
}
func setHas(element: T) -> Bool {
return backingStore.filter { $0 == element }.count != 0
}
mutating func append(element: T) {
guard !setHas(element) else { return }
backingStore.append(element)
}
}
//ใ“ใฎ`Unique`ใจใ„ใ†ๆง‹้€ ไฝ“ใฏใจใฆใ‚‚ใ‚ทใƒณใƒ—ใƒซใงใ™ใ€‚`Comparable`ใซๆบ–ๆ‹ ใ—ใŸๅž‹ใฎ่ฆ็ด ใ‚’`append`ใ™ใ‚‹ใจๅ†…้ƒจ็š„ใช้…ๅˆ—ใซ่ฆ็ด ใ‚’่ฟฝๅŠ ใ—ใพใ™ใ€‚้…ๅˆ—ไธญใซๅŒใ˜่ฆ็ด ใŒๅญ˜ๅœจใ™ใ‚‹ๅ ดๅˆใฏ่ฟฝๅŠ ใ—ใพใ›ใ‚“ใ€‚
//
//ใใ‚Œใงใฏ`Unique`ใ‚’ใƒ†ใ‚นใƒˆใ—ใฆใฟใพใ—ใ‚‡ใ†๏ผ
var mySet = Unique<String>()
// Our set can
mySet.setHas("A Careless Cat") //false
mySet.append("A Careless Cat")
mySet.setHas("A Careless Cat") //true
mySet.append("A Careless Cat") //ใ™ใงใซใ‚ใ‚‹ๆ–‡ๅญ—ๅˆ—
mySet.count //ใพใ 1ใงใ™๏ผ
//ใ‚‚ใ†ใกใ‚‡ใฃใจ้ …็›ฎ่ฟฝๅŠ ใ—ใพใ—ใ‚‡ใ†๏ผ
mySet.append("A Dangerous Dog[f:id:vasilyjp:20160324103132p:plain]")
mySet.append("A Diamond Dog")
mySet.append("Petty Parrot")
mySet.append("North American Reckless Raccoon")
mySet.append("A Monadic Mole")
//
//for animal in mySet {
// println(animal)
//}
let vowels = ["A","E","I","O","U"]
var gen = vowels.generate()
while let letter = gen.next() {
print(letter)
}
//`generate()`ใฏ`SequenceType`ใƒ—ใƒญใƒˆใ‚ณใƒซใฎใƒกใ‚ฝใƒƒใƒ‰ใงใ™ใ€‚
//`Unique`ใฏ`SequenceType`ใƒ—ใƒญใƒˆใ‚ณใƒซใซๆบ–ๆ‹ ใ—ใฆใชใ„ใฎใง`for in`ใŒๅ‹•ใ‹ใชใ„ใฎใงใ™ใ€‚
//ใใ‚Œใงใฏใ€`SequenceType`ใƒ—ใƒญใƒˆใ‚ณใƒซใซๅฟ…่ฆใชๆกไปถใ‚’่ฆ‹ใฆๅฎŸ่ฃ…ใ—ใฆใฟใพใ—ใ‚‡ใ†๏ผ
//public protocol SequenceType {
// associatedtype Generator : GeneratorType
// public func generate() -> Self.Generator
//}
//`generate()`ใฎๆˆปใ‚Šๅ€คใฎๅž‹ใฏๅž‹ๆŽจ่ซ–ใŒๅŠนใใฎใงใ€`typealias Generator = ...`ใ‚’ๆ›ธใๅฟ…่ฆใฏใ‚ใ‚Šใพใ›ใ‚“ใ€‚
//
//`Unique`ใ‚’`SequenceType`ใƒ—ใƒญใƒˆใ‚ณใƒซใซๆบ–ๆ‹ ใ•ใ›ใฆใ€`generate()`ใƒกใ‚ฝใƒƒใƒ‰ใ‚’ๅฎŸ่ฃ…ใ™ใ‚‹ในใใงใ™ใŒใ€ใพใ `GeneratorType`ใฎใ“ใจใ‚’ใ‚ˆใ็Ÿฅใ‚Šใพใ›ใ‚“ใ€‚
//ใใ‚Œใงใฏ`GeneratorType`ใ‚’ใƒใ‚งใƒƒใ‚ฏใ—ใพใ—ใ‚‡ใ†๏ผ
//
//##Generator ใจใฏ๏ผŸ
//public protocol GeneratorType {
// associatedtype Element
// public mutating func next() -> Self.Element?
//}
//`SequenceType`ใจๅŒใ˜ใ‚ˆใ†ใซไธ€ใคใฎใƒกใ‚ฝใƒƒใƒ‰ใ—ใ‹ใ‚ใ‚Šใพใ›ใ‚“ใ€‚`next()`ใฎๆˆปใ‚Šๅ€คใฎๅž‹ใฏใ€`Element`ๅž‹ใจใชใฃใฆใ„ใพใ™ใŒๅž‹ๆŽจ่ซ–ใŒๅŠนใใพใ™ใ€‚`[String]`ใงใ‚ใ‚Œใฐใ€ๅฎŸ้š›ใซใฏ`String`ใซใชใ‚Šใพใ™ใ€‚
//`Generator`ใฏ`next()`ใƒกใ‚ฝใƒƒใƒ‰ใงใ€ไฟๆŒใ—ใฆใ„ใ‚‹ใƒ‡ใƒผใ‚ฟใ‚’้ †็•ชใซ่ฟ”ใ—ใพใ™ใ€‚ๆœ€ๅพŒใฎใƒ‡ใƒผใ‚ฟใ‚’่ฟ”ใ—ใŸใ‚ใจๅ†ๅบฆ`next()`ใ‚’ๅ‘ผใถใจ`nil`ใ‚’่ฟ”ใ—ใพใ™ใ€‚
//
//`GeneratorType`ใ‚’ไฝฟใ„็ต‚ใ‚ใ‚‹ใจๅ†ๅˆฉ็”จใงใใพใ›ใ‚“ใ€‚ๅŒใ˜ใƒ‡ใƒผใ‚ฟใ‚ปใƒƒใƒˆใ‚’ใ‚‚ใ†ไธ€ๅบฆ`GeneratorType`ใง่ชญใฟใŸใ‘ใ‚Œใฐใ€ๆ–ฐใ—ใ`GeneratorType`ใ‚’็”Ÿๆˆใ™ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™ใ€‚
//
//ใใ—ใฆใ€`generate()`ใ‚’ๅฎŸ่ฃ…ใ™ใ‚‹ๆ™‚ใซๆˆปใ‚Šๅ€คใฎ`GeneratorType`ใจไป–ใฎ`GeneratorType`ๅค‰ๆ•ฐใฎ็Šถๆ…‹ใ‚’ๅ…ฑๆœ‰ใ—ใชใ„ใ‚ˆใ†ใซใ—ใชใ‘ใ‚Œใฐใ„ใ‘ใพใ›ใ‚“ใ€‚
//
//ๅŸบๆœฌ็š„ใชไธŠ้™ใŒใ‚ใ‚‹`GeneratorType`:
struct CountToGenerator: GeneratorType {
private var limit: Int
private var currentCount = 0
init(limit: Int) {
self.limit = limit
}
mutating func next() -> Int? {
guard currentCount < limit else { return nil }
defer { currentCount += 1 }
return currentCount
}
}
var goTillTen = CountToGenerator(limit: 10)
while let num = goTillTen.next() {
print(num)
}
//`SequenceType`ใจ`GeneratorType`ใ‚’ๅญฆใ‚“ใ ใฎใงใ€`Unique`ๅฐ‚็”จใฎ`GeneratorType`ใ‚’ไฝœใ‚Šใพใ—ใ‚‡ใ†๏ผ
//class UniqueGenerator<T>: GeneratorType {
// private var _generationMethod: () -> T?
// init(_generationMethod: () -> T?) {
// self._generationMethod = _generationMethod
// }
//
// func next() -> T? {
// return _generationMethod()
// }
//}
//
//extension Unique: SequenceType {
// func generate() -> UniqueGenerator<T> {
// var iteration = 0
//
// return UniqueGenerator {
// if iteration < self.backingStore.count {
// let result = self.backingStore[iteration]
// iteration += 1
// return result
// }
//
// return nil
// }
// }
//}
//ใ“ใ“ใพใงๅญฆใ‚“ใ ใ“ใจใงใ€`Unique`ใฎ`GeneratorType`ใฎๅฎŸ่ฃ…ใŒใงใใพใ—ใŸใŒใ€ใ‚‚ใ†ๅฐ‘ใ—็Ÿญใๆ›ธใ‘ใพใ™ใ€‚
//`AnyGenerator`ใจใ„ใ†Genericใ‚ฟใ‚คใƒ—ใ‚’ไฝฟใ†ใจ`UniqueGenerator`ใ‚’ไฝœใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใพใ›ใ‚“ใ€‚
extension Unique: SequenceType {
func generate() -> AnyGenerator<T> {
var iteration = 0
return AnyGenerator {
if iteration < self.backingStore.count {
let result = self.backingStore[iteration]
iteration += 1
return result
}
return nil
}
}
}
//ใ‚‚ใ†ไธ€ๅบฆ`for in`ใƒซใƒผใƒ—ใ‚’ๆ›ธใใพใ—ใ‚‡ใ†๏ผ
for item in mySet {
print(item)
}
//ใ‚„ใฃใจๅ‹•ใใพใ—ใŸ๏ผ
//`map`ใจ`filter`ใ‚‚ๅ‹•ใใพใ™๏ผใ‚„ใฃใŸ๏ผ
let cnt = mySet.map { Int($0.characters.count) } //[14, 15, 13, 12, 31, 14]
mySet.filter { $0.characters.first != "A" } //["Petty Parrot", "North American Reckless Raccoon"]
//#Controlling Sequences with Sequences
//
//`SequenceType`ใฎๅฎŸ่ฃ…ๆฌก็ฌฌใงใ€ใจใฆใ‚‚ๅคงใใ„ใƒชใ‚นใƒˆใ‚„็„ก้™ใƒชใ‚นใƒˆใ‚’ไฝœใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚
//ใใ†ใ„ใฃใŸใƒชใ‚นใƒˆใ‹ใ‚‰ๅ…ˆ้ ญใ‹ใ‚‰`n`ๅ€‹ๅ–ใ‚Šๅ‡บใใ†ใจใ™ใ‚‹ใจใ€ใใฎใพใพไฝฟใ†ใจ็„ก้™ใƒซใƒผใƒ—ใซใชใฃใฆใ—ใพใ„ใพใ™ใ€‚
//
//ไพ‹ใˆใฐไธ‹่จ˜ใฎ`ThePattern`ใฏ็„ก้™ใƒชใ‚นใƒˆใงใ™ใ€‚
//`for in`ใงไฝฟใ†ใจใ€`Generator`ใŒ`nil`ใ‚’่ฟ”ใ•ใชใ„ใŸใ‚ใ€ๆฐธ้ ใซ`0`ใ‹`1`ใ‚’่ฟ”ใ—ใพใ™ใ€‚
class ThePattern: SequenceType {
func generate() -> AnyGenerator<Int> {
var isOne = true
return AnyGenerator {
isOne = !isOne
return isOne ? 1 : 0
}
}
}
// ็„ก้™ใƒซใƒผใƒ—
for i in ThePattern() {
print(i)
}
//ใ“ใฎ็„ก้™ใƒชใ‚นใƒˆใ‹ใ‚‰
class First<S: SequenceType>: SequenceType {
private let limit: Int
private var counter: Int = 0
private var generator: S.Generator
init(_ limit: Int, sequence: S) {
self.limit = limit
self.generator = sequence.generate()
}
func generate() -> AnyGenerator<S.Generator.Element> {
return AnyGenerator {
defer { self.counter += 1 }
guard self.counter < self.limit else { return nil }
return self.generator.next()
}
}
}
for item in First(5, sequence: ThePattern()) {
print(item) // 0 1 0 1 0
}
//ใ„ใ„ใงใ™ใญ๏ผ
//`First(n, sequence: s)` ใ‚’ๅ‘ผใณๅ‡บใ™ใจใ€`s`ใฎๅ…ˆ้ ญ`n`ๅ€‹ใฎ่ฆ็ด ใ‚’ๅ–ใ‚Šๅ‡บใ›ใพใ™ใ€‚
//`s`ใŒ็„ก้™ใƒชใ‚นใƒˆใ ใจใ—ใฆใ‚‚ๆœ€ๅˆใฎ`n`ๅ€‹ใ—ใ‹ใƒใ‚งใƒƒใ‚ฏใ—ใชใ„ใฎใงๅŠน็އ็š„ใงใ™ใ€‚
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment