Int类型不符合协议序列

时间:2017-02-05 23:20:47

标签: arrays swift swift3 sequence for-in-loop

我在Swift 3中有以下代码:

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

我正在检查索引[number]上的值是否始终高于索引[number + 1]上的值。我收到一个错误:

  

Int类型不符合协议序列

有什么想法吗?

7 个答案:

答案 0 :(得分:19)

可能很快。 您可以使用此迭代。

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

答案 1 :(得分:4)

错误是因为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)

答案 2 :(得分:2)

如果尝试枚举数组而不是枚举数组,也可能会发生此错误。例如:

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

}

应该是:

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

}

答案 3 :(得分:0)

错误是因为 number 不是索引,而是每次迭代时数组的元素。您可以像这样修改代码:

password

或者使用排序方法有一个技巧,但这是一种黑客攻击(是的,子索引是正确的,但看起来像倒置了;你可以直接在Playground上试试):

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

答案 4 :(得分:0)

这可能有点晚了,但你可以做到:

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 { }

只给出一个可以是起始值或结束值的值,这样就无法确定for循环必须运行多长时间。

有关详细信息,请参阅Apple's swift control flow documnetation

答案 5 :(得分:0)

因此,首先您需要了解什么是序列。  一种提供对其元素的顺序,迭代访问的类型。

序列是您可以一次浏览一个值的列表。遍历序列元素的最常见方法是使用for-in循环:

让oneTwoThree = 1 ... 3。 //顺序

for循环实际上意味着

有关序列{}中的数字

因此您需要使用 表示0中的数字。<(numbers.count-1){}

答案 6 :(得分:0)

对我来说,当我尝试编写for循环而不是数组,而是数组的单个元素时,会发生此错误。

例如:

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

for its in item
{
   print(its)
}

这会产生如下错误:类型Int不符合协议“序列”

因此,如果在for循环中遇到此错误,请检查是否在循环数组。