web-dev-qa-db-ja.com

タイプIntはプロトコルシーケンスに準拠していません

Swift 3に次のコードがあります:

var numbers = [1,2,1]
for number in numbers.count - 1 { // error
    if numbers[number]  < numbers[number + 1] {
        print(number)
    }
}

インデックス[数値]の値が常にインデックス[数値+ 1]の値よりも高いかどうかを確認しています。エラーが発生しています:

タイプIntはプロトコルシーケンスに準拠していません

何か案が?

8
Toby V.

スウィフトかもしれません。この反復を使用できます。

for number in 0..<(numbers.count-1)
26
mqz.kim

エラーは、IntSequenceではないためです。既に推奨されているように範囲を作成できます。これは、シーケンスに適合し、for inを使用した反復を許可します。

Intをシーケンスに適合させる1つの方法は次のとおりです。

extension Int: Sequence {
    public func makeIterator() -> CountableRange<Int>.Iterator {
        return (0..<self).makeIterator()
    }
}

これにより、for inでシーケンスとして使用できるようになります。

for i in 5 {
    print(i)
}

しかし、私はこれを行うことをお勧めしません。プロトコルの威力を示すためだけのものですが、実際のコードベースではおそらく混乱するでしょう。

あなたの例から、あなたはコレクションの連続した要素を比較しようとしているように見えます。カスタムイテレータは、コードをかなり読みやすく保ちながら、まさにそれを行うことができます。

public struct ConsecutiveSequence<T: IteratorProtocol>: IteratorProtocol, Sequence {
    private var base: T
    private var index: Int
    private var previous: T.Element?

    init(_ base: T) {
        self.base = base
        self.index = 0
    }

    public typealias Element = (T.Element, T.Element)

    public mutating func next() -> Element? {
        guard let first = previous ?? base.next(), let second = base.next() else {
            return nil
        }

        previous = second

        return (first, second)
    }
}

extension Sequence {
    public func makeConsecutiveIterator() -> ConsecutiveSequence<Self.Iterator> {
        return ConsecutiveSequence(self.makeIterator())
    }
}

次のように使用できます。

for (x, y) in [1,2,3,4].makeConsecutiveIterator() {
    if (x < y) {
        print(x)
    }
}

上記の例では、イテレータは次のペアを調べます。

(1, 2)
(2, 3)
(3, 4)
4
Anurag

これは少し遅いかもしれませんが、次のことができます。

for number in numbers { }

の代わりに:

for number in numbers.count - 1 { }

Forループが機能するには、シーケンス(範囲)が必要です。シーケンスは、値の記述、終了値、およびその間のすべてで構成されます。つまり、forループは、etherのある範囲をループするように指示できます。

for number in 0...numbers.count-1 { }   `or`   for number in numbers { } 

両方の例は、nesaseryシーケンスを示しています。どこに:

 for number in numbers.count - 1 { }

開始値または終了値のいずれかになる可能性のある1つの値のみを指定し、forループの実行に必要な時間を計算することを不可能にします。

詳細については、 AppleのSwift制御フロー文書化 を参照してください。

2
Dzyuv001

エラーは、numberはインデックスではなく、各反復の配列の要素であるためです。次のようにコードを変更できます。

var numbers = [1,2,1,0,3]
for number in 0..<numbers.count - 1 {
    if numbers[number] < numbers[number + 1] {
        print(numbers[number])
    }
}

または、sortメソッドを使用するトリックがありますが、それは一種のハックです(そして、はい、サブインデックスは正しいですが、逆に見えます; Playgroundで直接これを試すことができます):

var numbers = [1,2,1,0,3]
numbers.sort {
    if $0.1 < $0.0 {
        print ($0.1)
    }
    return false
}
0
nbloqs