[Swift] あると便利（かも）な イテレータ

**便利（かも）な イテレータを2つ紹介します**

# 1. 隣の要素も

配列で、隣の要素を見たり、比べたりするとき・・・

![withNext.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/58e476ca-d2b5-981e-4713-13b85d5c12e9.png)

↑ 上の図で、①②③・・・⑩の順番で、隣の要素とのタプルを受け取るイテレータ。

配列の要素数を$N$とすると、受け取るタプルの総数は$(N-1)$個。

### 使い方

```swift:withNext(_:)
let A = Array(0...10)
for a in withNext(A) {
    print(a)
}
//(0, 1)
//(1, 2)
//(2, 3)
//(3, 4)
//(4, 5)
//(5, 6)
//(6, 7)
//(7, 8)
//(8, 9)
//(9, 10)
```

もし、逆順（⑩⑨⑧・・・①の順番で）受け取りたい場合は、一旦`Array`にしてから`reversed`します。（他のイテレータと同様）

```swift:逆順（withNext(_:)）
let A = Array(0...10)
for a in Array(withNext(A)).reversed() {
    print(a)
}
//(9, 10)
//(8, 9)
//(7, 8)
//(6, 7)
//(5, 6)
//(4, 5)
//(3, 4)
//(2, 3)
//(1, 2)
//(0, 1)
```



# 2. 端と端から

配列で、先頭と最後の要素、先頭から2番目と最後から2番目の要素、・・・

![wthFar.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/e8f53f1c-9003-751d-624b-fad917498562.png)

↑ 上の図で、①②③・・・⑥の順番で、端と端のタプル、その内側の要素のタプル、・・・を受け取るイテレータ。

配列の要素数を$N$とすると、受け取るタプルの総数は$\lceil\frac{N}{2}\rceil$個。
要素数が奇数の場合は、上の図のとおり、最後は中央の要素が2個のタプルとなる。

### 使い方

```swift:withFarSide(_:)
let A = Array(0...10)
for a in withFarSide(A) {
    print(a)
}
//(0, 10)
//(1, 9)
//(2, 8)
//(3, 7)
//(4, 6)
//(5, 5)
```

逆順です

```swift:逆順（withFarSide(_:)）
let A = Array(0...10)
for a in Array(withFarSide(A)).reversed() {
    print(a)
}
//(5, 5)
//(4, 6)
//(3, 7)
//(2, 8)
//(1, 9)
//(0, 10)
```

# 実装

_例題は`Array`で説明しましたが、`Sequence`型で実装しているので、`Set`や`Dictionary`でも使うことができます（需要があるか不明ですが）。
性能も意識して`inlinable`関数とし、`Sendable`にも準拠しました。_

```swift:withNext
@inlinable
public func withNext<Sequence1>(_ sequence1: Sequence1) -> withNextSequence<Sequence1> {
    return withNextSequence(sequence1)
}
@frozen
public struct withNextSequence<Sequence1: Sequence>: Sequence {
    @usableFromInline
    internal var _baseStream1: Sequence1.Iterator
    @usableFromInline
    internal var _baseStream2: IndexingIterator<[Sequence1.Element]>
    @usableFromInline
    internal var _left: Sequence1.Element? = nil
    @usableFromInline
    internal var _mid: Int
    @inlinable
    internal init(_ sequence1: Sequence1) {
        _baseStream1 = sequence1.makeIterator()
        _baseStream2 = sequence1.reversed().makeIterator()
        _mid = (sequence1.underestimatedCount + 1) / 2
    }
}
extension withNextSequence: IteratorProtocol {
    public typealias Element = (Sequence1.Element, Sequence1.Element)
    @inlinable
    public mutating func next() -> Element? {
        guard let _next = _baseStream1.next() else { return nil }
        if _left == nil {
            let _next1 = _next
            guard let _next2 = _baseStream1.next() else { return nil }
            _left = _next2
            return (_next1, _next2)
        }
        let _next1 = _left!
        _left = _next
        return (_next1, _next)
    }
}
extension withNextSequence: Sendable where Sequence1: Sendable, Element: Sendable, Sequence1.Iterator: Sendable { }
```

```swift:withFarSide
@inlinable
public func withFarSide<Sequence1>(_ sequence1: Sequence1) -> withFarSequence<Sequence1> {
    return withFarSequence(sequence1)
}
@frozen
public struct withFarSequence<Sequence1: Sequence>: Sequence {
    @usableFromInline
    internal var _baseStream1: Sequence1.Iterator
    @usableFromInline
    internal var _baseStream2: IndexingIterator<[Sequence1.Element]>
    @usableFromInline
    internal var _left: Sequence1.Element? = nil
    @usableFromInline
    internal var _mid: Int
    @inlinable
    internal init(_ sequence1: Sequence1) {
        _baseStream1 = sequence1.makeIterator()
        _baseStream2 = sequence1.reversed().makeIterator()
        _mid = (sequence1.underestimatedCount + 1) / 2
    }
}
extension withFarSequence: IteratorProtocol {
    public typealias Element = (Sequence1.Element, Sequence1.Element)
    @inlinable
    public mutating func next() -> Element? {
        guard _mid > 0 else { return nil }
        guard let left = _baseStream1.next(),
              let right = _baseStream2.next() else { return nil }
        _mid -= 1
        return (left, right)
    }
}
extension withFarSequence: Sendable where Sequence1: Sendable, Element: Sendable, Sequence1.Iterator: Sendable { }
```

ジェネリックに実装すると、なんだか面倒で行数も多くなってしまいます。
`Array`専用の`イテレータ`なら、断然簡単に書けます。

```swift:withNext
struct withNext<Element>: Sequence, IteratorProtocol, Sendable where Element: Sendable  {
    @usableFromInline
    internal let array: [Element]
    @usableFromInline
    internal var index = 0
    init(_ elements: [Element]) { array = elements }
    @inlinable
    public mutating func next() -> (Element, Element)? {
        if index < array.count - 1 {
            defer { index += 1 }
            return (array[index], array[index + 1])
        } else {
            return nil
        }
    }
}
```


```swift:withFarSide
struct withFarSide<Element>: Sequence, IteratorProtocol, Sendable where Element: Sendable  {
    @usableFromInline
    internal let array: [Element]
    @usableFromInline
    internal var index = 0
    init(_ elements: [Element]) { array = elements }
    @inlinable
    public mutating func next() -> (Element, Element)? {
        if index < (array.count + 1) / 2 {
            defer { index += 1 }
            return (array[index], array[array.count - 1 - index])
        } else {
            return nil
        }
    }
}
```

# 応用例

単純な応用例ですが、以下にあげておきます。

```swift
let array1 = [1, 2, 3, 4]
let array2 = [1, 2, 5, 4]
let array3 = [1, 2, 2, 1]

extension Array where Element: Comparable {
    var isSimpleIncrease: Bool { withNext(self).allSatisfy { $0.0 < $0.1 } }
    var isPalindrome: Bool { withFarSide(self).allSatisfy { $0.0 == $0.1 } }
}
```


### 1. 単純増加判定

```swift
let a1 = array1.isSimpleIncrease // true 
let a2 = array2.isSimpleIncrease // false
let a3 = array3.isSimpleIncrease // false
```

### 2. 回文判定


```swift
let a4 = array1.isPalindrome // false
let a5 = array2.isPalindrome // false
let a6 = array3.isPalindrome // true 
```