我在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类型不符合协议序列
有什么想法吗?
答案 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循环中遇到此错误,请检查是否在循环数组。