web-dev-qa-db-fra.com

Le type Int n'est pas conforme à la séquence de protocole

J'ai le code suivant dans Swift 3:

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

Je vérifie si la valeur de l'index [numéro] est toujours supérieure à la valeur de l'index [nombre + 1]. Je reçois une erreur:

Le type Int n'est pas conforme à la séquence de protocole

Une idée?

5
Toby V.

Ce peut être Swift . Vous pouvez utiliser cette itération.

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

L'erreur est due au fait que Int n'est pas un Sequence. Vous pouvez créer une plage comme déjà suggéré, qui est conforme à une séquence et permet l'itération à l'aide de for in.

Une façon de rendre Int conforme à une séquence est la suivante:

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

Ce qui permettrait alors de l'utiliser comme une séquence avec for in.

for i in 5 {
    print(i)
}

mais je ne recommanderais pas cela. C'est seulement pour démontrer la puissance des protocoles, mais serait probablement déroutant dans un code réel.

D'après votre exemple, il semblerait que vous essayiez de comparer des éléments consécutifs de la collection. Un itérateur personnalisé peut le faire tout en maintenant le code lisible:

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())
    }
}

qui peut être utilisé comme:

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

Dans l'exemple ci-dessus, l'itérateur examine les paires suivantes:

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

C'est peut-être un peu tard mais tu aurais pu le faire:

for number in numbers { }

au lieu de:

for number in numbers.count - 1 { }

Pour qu'une boucle for fonctionne, une séquence (plage) est nécessaire. Une séquence consiste à énoncer une valeur, une valeur de fin et tout le reste. Cela signifie qu’on peut dire à une boucle for de parcourir une plage avec de l’éther

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

Les deux exemples donnent les séquences nesasery. Tandis que: 

 for number in numbers.count - 1 { }

Ne donne qu'une valeur qui pourrait être la valeur de début ou la valeur de fin, rendant impossible de déterminer le nombre de fois que la boucle for devra s'exécuter. 

Pour plus d'informations, voir Documentation du flux de contrôle Swift d'Apple

0
Dzyuv001

L'erreur est due au fait que number n'est pas un index, mais l'élément du tableau à chaque itération. Vous pouvez modifier votre code comme ceci:

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

Ou bien il y a un truc en utilisant la méthode de tri, mais c'est un peu un hack (et oui, les sous-index sont corrects, mais ressemblent à inversés; vous pouvez essayer cela directement sur un terrain de jeu):

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