Тип 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 не соответствует последовательности протокола

Есть идеи?


person Toby V.    schedule 05.02.2017    source источник
comment
numbers.count - 1 это не последовательность, это целое число. Так что это не может быть повторено. Вам нужно что-то вроде for number in numbers. кстати что это за язык?   -  person Nic    schedule 06.02.2017
comment
Swift 3, я знаю, что это не сработает, но мне нужна команда, которая будет зацикливать этот код для чисел. количество - 1 раз.   -  person Toby V.    schedule 06.02.2017
comment
for index in numbers.indices { Кстати, вам нужно проверить, есть ли другой элемент после фактического индекса if index + 1 < numbers.count {, прежде чем пытаться получить доступ к следующему элементу в вашем массиве.   -  person Leo Dabus    schedule 06.02.2017


Ответы (7)


Может быть быстро. Вы можете использовать эту итерацию.

for number in 0..<(numbers.count-1)
person mqz.kim    schedule 05.02.2017

Ошибка в том, что Int не является Sequence. Вы можете создать диапазон, как уже предлагалось, который соответствует последовательности и позволяет выполнять итерацию с использованием for in.

Один из способов привести Int в соответствие с последовательностью:

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)
person Anurag    schedule 06.02.2017

Это может быть немного поздно, но вы могли бы сделать:

for number in numbers { }

вместо:

for number in numbers.count - 1 { }

Для работы цикла for необходима последовательность (диапазон). Последовательность состоит из указания значения, конечного значения и всего, что между ними. Это означает, что цикл for может пройти через диапазон с эфиром.

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

Оба примера дают последовательности nesasery. В то время как:

 for number in numbers.count - 1 { }

Дает только одно значение, которое может быть либо начальным, либо конечным значением, что делает невозможным вычисление того, сколько времени придется выполнять цикл for.

Для получения дополнительной информации см. документацию Apple по быстрому управлению потоком

person Dzyuv001    schedule 28.07.2017

Эта ошибка также может возникнуть, если вы попытаетесь перечислить массив вместо перечисляемого массива. Например:

for (index, element) in [0, 3, 4] { 

}

Должно быть:

for (index, element) in [0, 3, 4].enumerated() { 

}
person ScottyBlades    schedule 25.06.2020

Итак, сначала вам нужно понять, что такое sequence. Тип, обеспечивающий последовательный итеративный доступ к своим элементам.

Последовательность — это список значений, которые вы можете проходить по одному за раз. Наиболее распространенным способом перебора элементов последовательности является использование цикла for-in:

пусть одинДваТри = 1...3. // Последовательность

цикл for на самом деле означает

Для числа в последовательностях {}

Итак, вам нужно использовать для числа в 0..‹(numbers.count-1) {}

person Rajasekaran Gopal    schedule 12.11.2019

Ошибка в том, что число — это не индекс, а элемент массива на каждой итерации. Вы можете изменить свой код следующим образом:

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

Или есть трюк с использованием метода сортировки, но это своего рода хак (и да, субиндексы правильные, но выглядят как перевернутые; вы можете попробовать это прямо на игровой площадке):

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

Для меня эта ошибка возникла, когда я попытался написать цикл for не для массива, а для одного элемента массива.

Например:

let array = [1,2,3,4]
let item = array[0]

for its in item
{
   print(its)
}

Это дает ошибку типа: Тип Int не соответствует "последовательности" протокола.

Итак, если вы получаете эту ошибку в цикле for, проверьте, зацикливаете ли вы массив или нет.

person V.S    schedule 11.12.2019