### 序列

``````protocol Sequence {
associatedtype Iterator: IteratorProtocol
func makeIterator() -> Iterator
}
``````

### IteratorProtocol

``````protocol IteratorProtcol {
associatedtype Element
mutating func next() -> Element?
}
``````

`Sequence` 协议是基于 `IteratorProtocol` 构建的，而 `Sequence` 协议又为我们所需的功能提供了支撑。我们将以链表 (LinkedList) 为例。链表这个例子非常适合，因为它与 `Sequence` 贴合得很紧密：我们需要查看链表中一个元素，然后不停地查看下一个元素。

### 示例：链表

``````indirect enum LinkedListNode<T> {
case end
}

}
}

mutating func next() -> T? {
switch current {
case let .value(element, next):
current = next
return element
case .end:
return nil
}
}
}
``````

``````let iterator = LinkedListIterator<String>(current: linkedList)
print(iterator.next()) // => “A”
``````

``````let iterator = LinkedListIterator<String>(current: linkedList)
print(iterator.next())
print(iterator.next()) // => “B”
``````

``````let numberOfAdmins = users.filter({ \$0.isAdmin }).count // => fine

extension Sequence {

func count(_ shouldCount: (Iterator.Element) -> Bool) -> Int {

var count = 0

for element in self {

if shouldCount(element) {

count += 1

}

}

return count

}

}
``````

`zip(sequence, sequence.dropFirst()) // Sequence<(T, T)>`

``````extension Sequence

where Self.SubSequence: Sequence {

Self.SubSequence.Iterator.Element == Self.Iterator.Element {

func eachPair() -> AnySequence<(Iterator.Element, Iterator.Element)> {

return AnySequence(zip(self, self.dropFirst()))

}

}
``````

### 集合

``````protocol Collection {
associatedtype Index: Comparable
var startIndex: Index
var endIndex: Index
subscript(position: Index) -> Iterator.Element { get }
func index(after index: Index) -> Index
}
``````

``````func forEach(_ block: (Element) -> Void) {
var currentIndex = self.startIndex
while currentIndex < self.endIndex {
block(self[currentIndex])
currentIndex = self.index(after: currentIndex)
}
}
``````

``````
extension APIErrorCollection: Collection {

var startIndex: Int {

return _errors.startIndex

}

var endIndex: Int {

return _errors.endIndex

}

func index(after index: Int) -> Int {

return _errors.index(after: index)
}

subscript(position: Int) -> APIError {

return _errors[position]

}

}
``````

``````
struct APIErrorCollection {

fileprivate let _errors: [APIError]

}

extension APIErrorCollection: Collection {

// ...

}

// compiles!

``````

### 双向集合

``````
protocol Collection {

//...

func index(after index: Index) -> Index

}

protocol BidirectionalCollection: Collection {

func index(before index: Index) -> Index

}

``````

``````
var last: Iterator.Element? {

guard !self.isEmpty else { return nil }

let indexOfLastItem = self.index(before: self.endIndex)

return self[indexOfLastItem]

}

``````

### 其它协议

• `RandomAccessCollection`：可以更快地访问值。您可以直接跳转到想要获取的那个元素，而不必去逐步遍历。
• `RangeReplaceableCollection`：允许您使用其它内容来将集合中间的某个部分替换掉。
• `MutableCollection`：允许您对这些值进行读取或修改。

### 问答时间到！

Soroush：在您构建内容的大多数时候，`Iterator` 类型通常都只在内部起作用，或者说通常只有 Swift 标准库才会使用它。您完全不用去在乎这个类型，但是有时借助这个类型您可以去手动执行某些操作，比如说我们假设您正在几个不同的页面之间来回切换，那么每次您可以选择去持有这些页面的迭代器，而不是选择去持有这些页面的集合。如果持有的是迭代器的话，那么每次您切换页面的时候，您只需要调用 `next` 即可，它就能够为您展示下一个元素，以此类推，这样您就可以借助 `Iterator` 类型来增强代码的表达力。