有没有办法在Swift中使用反向范围?例如:
for i in 5...1 { // do something }
是一个无限循环。在较新版本的Swift中,该代码可以编译,但在运行时会出现错误:致命错误:无法形成上限〈下限的范围我知道我可以用1..5来代替,计算j = 6 - i并使用j作为我的索引。我只是想知道是否有更清晰的东西?
1..5
j = 6 - i
j
dgenwo3n1#
针对最新Swift 3进行更新(在Swift 4中仍然有效)
可以对范围使用reversed()方法
reversed()
for i in (1...5).reversed() { print(i) } // 5 4 3 2 1
或stride(from:through:by:)方法
stride(from:through:by:)
for i in stride(from:5,through:1,by:-1) { print(i) } // 5 4 3 2 1
stride(from:to:by:)类似,但不包括最后一个值
stride(from:to:by:)
for i in stride(from:5,to:0,by:-1) { print(i) } // 5 4 3 2 1
更新最新Swift 2
首先,协议扩展改变了reverse的使用方式:for i in (1...5).reverse() { print(i) } // 5 4 3 2 1Stride在Xcode 7 Beta 6中进行了重新设计。新的用法是:
reverse
for i in (1...5).reverse() { print(i) } // 5 4 3 2 1
for i in 0.stride(to: -8, by: -2) { print(i) } // 0 -2 -4 -6 for i in 0.stride(through: -8, by: -2) { print(i) } // 0 -2 -4 -6 -8
它也适用于Doubles:
Doubles
for i in 0.5.stride(to:-0.1, by: -0.1) { print(i) }
请注意此处的浮点比较范围。
Swift 1.2的早期编辑:从Xcode 6 Beta 4开始,by和ReverseRange不再存在:[
如果您只是想反转一个范围,则只需使用reverse函数即可:
for i in reverse(1...5) { println(i) } // prints 5,4,3,2,1
正如0x7fffffff发布的,有一个新的stride结构,可以用来迭代和增加任意整数。苹果还表示浮点支持即将到来。来源于他的回答:
for x in stride(from: 0, through: -8, by: -2) { println(x) // 0, -2, -4, -6, -8 } for x in stride(from: 6, to: -2, by: -4) { println(x) // 6, 2 }
2lpgd9682#
这种不对称性有一些令人不安的地方:
for i in (1..<5).reverse()
......与此相反:
for i in 1..<5 {
这意味着每次我想做一个反向范围,我必须记住把括号,加上我必须写在最后的.reverse(),突出像一个拇指痛,这是真的很难看相比,C风格的循环,这是对称的向上计数和向下计数,所以我倾向于使用C风格的循环代替,但在Swift 2. 2,C风格的for循环将消失!所以我不得不匆忙地用这个丑陋的.reverse()结构替换我所有递减的C风格for循环--一直想知道,为什么地球上没有一个反向范围操作符?但是等等!这是Swift -我们可以定义自己的操作符!!现在开始:
.reverse()
infix operator >>> { associativity none precedence 135 } func >>> <Pos : ForwardIndexType where Pos : Comparable>(end:Pos, start:Pos) -> ReverseRandomAccessCollection<(Range<Pos>)> { return (start..<end).reverse() }
所以现在我可以说:
for i in 5>>>1 {print(i)} // 4, 3, 2, 1
这只涵盖了我的代码中最常见的情况,但它 * 是 * 最常见的情况,所以这是我目前所需要的。我遇到了一个操作员的内部危机,我想使用>..,作为..<的反向,但这是不法律的的:看起来,你不能在一个非点之后使用点。我考虑过..>,但觉得它太难与..<区分。>>>的好处是它会向你尖叫:“down to!”(当然你可以自由地想出另一个运算符。但我的建议是:对于超对称,定义<<<来做..<所做的事情,现在你得到了<<<和>>>,它们是对称的,并且容易输入。)
>..
..<
..>
>>>
<<<
infix operator >>> : RangeFormationPrecedence func >>><Bound>(maximum: Bound, minimum: Bound) -> ReversedRandomAccessCollection<CountableRange<Bound>> where Bound : Comparable, Bound.Stride : Integer { return (minimum..<maximum).reversed() }
infix operator >>> : RangeFormationPrecedence func >>><Bound>(maximum: Bound, minimum: Bound) -> ReversedRandomAccessCollection<CountableRange<Bound>> where Bound : Comparable & Strideable { return (minimum..<maximum).reversed() }
infix operator >>> : RangeFormationPrecedence func >>><Bound>(maximum: Bound, minimum: Bound) -> ReversedRandomAccessCollection<Range<Bound>> where Bound : Strideable { return (minimum..<maximum).reversed() }
infix operator >>> : RangeFormationPrecedence func >>><Bound>(maximum: Bound, minimum: Bound) -> ReversedCollection<Range<Bound>> where Bound : Strideable { return (minimum..<maximum).reversed() }
ddarikpa3#
这个问题的答案似乎随着测试版的进展而有所改变。从测试版4开始,by()函数和ReversedRange类型都从语言中删除了。如果您希望创建一个反向范围,您的选项现在如下:1:创建一个正向范围,然后使用reverse()函数将其反向。
by()
ReversedRange
reverse()
for x in reverse(0 ... 4) { println(x) // 4, 3, 2, 1, 0 } for x in reverse(0 ..< 4) { println(x) // 3, 2, 1, 0 }
2:使用beta 4中添加的新stride()函数,其中包括用于指定开始和结束索引以及迭代次数的函数。
stride()
注意,我在这篇文章中还包含了新的互斥范围操作符。..被替换为..<。
..
**编辑:**苹果在Xcode 6 beta 5 release notes中添加了以下建议来处理这个问题:
已移除ReverseRange;使用lazy(x..这里有一个例子。
for i in lazy(0...5).reverse() { // 0, 1, 2, 3, 4, 5 }
f1tvaqid4#
Xcode 7,测试版2 (〈Swift 3.0):
for i in (1...5).reverse() { // do something }
根据Developer Documentation, available as of 8 Dec 2020更新Xcode 8.0+(Swift 3.0+):
reversed
let word = "Backwards" for char in word.reversed() { print(char, terminator: "") } // Prints "sdrawkcaB"
在这种情况下,集合周围的 Package 读取集合的内容,并以相反的顺序返回它们。
let reversedWord = String(word.reversed()) print(reversedWord) // Prints "sdrawkcaB"
for countdown in stride(from: 3, to: 0, by: -1) { print("\(countdown)...") } // 3... // 2... // 1...
如果from值大于to值,并且by值为负,则stride反向读取内容。如果from值小于to值,并且by值为正,则stride将按其原始顺序通读内容。
from
to
by
stride
t98cgbkg5#
雨燕3、4+:你可以这样做:
for i in sequence(first: 10, next: {$0 - 1}) { guard i >= 0 else { break } print(i) }
结果:10、9、8 ... 0
您可以按照自己的喜好进行定制。更多信息请阅读func sequence<T> reference
func sequence<T>
kadbb4596#
这可能是另一种方法。
(1...5).reversed().forEach { print($0) }
txu3uszq7#
Reverse()函数用于倒序编号。变量n:整数//输入数字对于1...n.reverse()中的i {打印(i)}
7条答案
按热度按时间dgenwo3n1#
针对最新Swift 3进行更新(在Swift 4中仍然有效)
可以对范围使用
reversed()
方法或
stride(from:through:by:)
方法stride(from:to:by:)
类似,但不包括最后一个值更新最新Swift 2
首先,协议扩展改变了
reverse
的使用方式:for i in (1...5).reverse() { print(i) } // 5 4 3 2 1
Stride在Xcode 7 Beta 6中进行了重新设计。新的用法是:
它也适用于
Doubles
:请注意此处的浮点比较范围。
Swift 1.2的早期编辑:从Xcode 6 Beta 4开始,by和ReverseRange不再存在:[
如果您只是想反转一个范围,则只需使用reverse函数即可:
正如0x7fffffff发布的,有一个新的stride结构,可以用来迭代和增加任意整数。苹果还表示浮点支持即将到来。
来源于他的回答:
2lpgd9682#
这种不对称性有一些令人不安的地方:
......与此相反:
这意味着每次我想做一个反向范围,我必须记住把括号,加上我必须写在最后的
.reverse()
,突出像一个拇指痛,这是真的很难看相比,C风格的循环,这是对称的向上计数和向下计数,所以我倾向于使用C风格的循环代替,但在Swift 2. 2,C风格的for循环将消失!所以我不得不匆忙地用这个丑陋的.reverse()
结构替换我所有递减的C风格for循环--一直想知道,为什么地球上没有一个反向范围操作符?但是等等!这是Swift -我们可以定义自己的操作符!!现在开始:
所以现在我可以说:
这只涵盖了我的代码中最常见的情况,但它 * 是 * 最常见的情况,所以这是我目前所需要的。
我遇到了一个操作员的内部危机,我想使用
>..
,作为..<
的反向,但这是不法律的的:看起来,你不能在一个非点之后使用点。我考虑过..>
,但觉得它太难与..<
区分。>>>
的好处是它会向你尖叫:“down to!”(当然你可以自由地想出另一个运算符。但我的建议是:对于超对称,定义<<<
来做..<
所做的事情,现在你得到了<<<
和>>>
,它们是对称的,并且容易输入。)Swift 3版本(Xcode 8种子6):
Swift 4版本(Xcode 9测试版3):
Swift 4.2版本(Xcode 10测试版1):
Swift 5版本(Xcode 10.2.1):
ddarikpa3#
这个问题的答案似乎随着测试版的进展而有所改变。从测试版4开始,
by()
函数和ReversedRange
类型都从语言中删除了。如果您希望创建一个反向范围,您的选项现在如下:1:创建一个正向范围,然后使用
reverse()
函数将其反向。2:使用beta 4中添加的新
stride()
函数,其中包括用于指定开始和结束索引以及迭代次数的函数。注意,我在这篇文章中还包含了新的互斥范围操作符。
..
被替换为..<
。**编辑:**苹果在Xcode 6 beta 5 release notes中添加了以下建议来处理这个问题:
已移除ReverseRange;使用lazy(x..
这里有一个例子。
f1tvaqid4#
Xcode 7,测试版2 (〈Swift 3.0):
根据Developer Documentation, available as of 8 Dec 2020更新Xcode 8.0+(Swift 3.0+):
reversed
-在这种情况下,集合周围的 Package 读取集合的内容,并以相反的顺序返回它们。
reversed
。这将创建一个具有相同内容但被反转的新集合:stride(from:to:by:)
反向返回集合的内容(以及按正常顺序):如果
from
值大于to
值,并且by
值为负,则stride
反向读取内容。如果
from
值小于to
值,并且by
值为正,则stride
将按其原始顺序通读内容。reverse()
成为reversed()
的时候。t98cgbkg5#
雨燕3、4+:你可以这样做:
结果:10、9、8 ... 0
您可以按照自己的喜好进行定制。更多信息请阅读
func sequence<T>
referencekadbb4596#
这可能是另一种方法。
txu3uszq7#
Reverse()函数用于倒序编号。
变量n:整数//输入数字
对于1...n.reverse()中的i {打印(i)}