有没有办法在Swift中使用反向范围?
例如:
for i in 5...1 {
// do something
}
Run Code Online (Sandbox Code Playgroud)
是一个无限循环.
我知道我可以使用1..5,计算j = 6 - i和使用j我的索引.我只是想知道是否有更清晰的东西?
Jac*_*ack 167
更新最新的Swift 3(仍在Swift 4中运行)
您可以reversed()在范围上使用该方法
for i in (1...5).reversed() { print(i) } // 5 4 3 2 1
Run Code Online (Sandbox Code Playgroud)
或stride(from:through:by:)方法
for i in stride(from:5,through:1,by:-1) { print(i) } // 5 4 3 2 1
Run Code Online (Sandbox Code Playgroud)
stide(from:to:by:) 类似但排除了最后一个值
for i in stride(from:5,to:0,by:-1) { print(i) } // 5 4 3 2 1
Run Code Online (Sandbox Code Playgroud)
更新最新的Swift 2
首先,协议扩展改变了reverse使用方式:
for i in (1...5).reverse() { print(i) } // 5 4 3 2 1
Stride已在Xcode 7 Beta 6中重新设计.新用法是:
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
Run Code Online (Sandbox Code Playgroud)
它也适用于Doubles:
for i in 0.5.stride(to:-0.1, by: -0.1) { print(i) }
Run Code Online (Sandbox Code Playgroud)
警惕这里的浮点比较边界.
早期编辑Swift 1.2:从Xcode 6 Beta 4开始,by和ReverseRange不再存在:[
如果您只是想要反转一个范围,那么您只需要反向功能:
for i in reverse(1...5) { println(i) } // prints 5,4,3,2,1
Run Code Online (Sandbox Code Playgroud)
由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
}
Run Code Online (Sandbox Code Playgroud)
mat*_*att 20
这种不对称有些令人不安的问题:
for i in (1..<5).reverse()
Run Code Online (Sandbox Code Playgroud)
......而不是这个:
for i in 1..<5 {
Run Code Online (Sandbox Code Playgroud)
这意味着每次我想做一个反向范围时,我必须记住放括号,加上我必须.reverse()在最后写出来,像拇指一样伸出来.与C风格的for循环相比,这是非常难看的,它们是对称计数和倒计时.所以我倾向于使用C风格的循环代替.但是在Swift 2.2中,C风格的循环正在消失!所以我不得不匆匆忙忙用这个丑陋的.reverse()构造来替换我所有递减的C风格的循环- 一直想知道,为什么地球上没有反向范围的算子呢?
可是等等!这是Swift - 我们被允许定义我们自己的运营商!! 开始了:
infix operator >>> {
associativity none
precedence 135
}
func >>> <Pos : ForwardIndexType where Pos : Comparable>(end:Pos, start:Pos)
-> ReverseRandomAccessCollection<(Range<Pos>)> {
return (start..<end).reverse()
}
Run Code Online (Sandbox Code Playgroud)
所以现在我可以说:
for i in 5>>>1 {print(i)} // 4, 3, 2, 1
Run Code Online (Sandbox Code Playgroud)
这仅仅涵盖了我的代码中最常见的情况,但它是最常见的情况,所以这就是我目前所需要的.
我对运营商提出了一种内部危机.我本来想使用>..,反之亦然..<,但这不合法:看起来你不能在非点之后使用点.我考虑过..>但是认为它太难以区分了..<.好消息>>>是它尖叫着你:" 下到!" (当然你可以自由地想出另一个操作员.但我的建议是:对于超对称,定义<<<做什么..<,现在你已经得到了<<<,>>>哪些是对称的,易于打字.)
infix operator >>> : RangeFormationPrecedence
func >>><Bound>(maximum: Bound, minimum: Bound) ->
ReversedRandomAccessCollection<CountableRange<Bound>>
where Bound : Comparable, Bound.Stride : Integer {
return (minimum..<maximum).reversed()
}
Run Code Online (Sandbox Code Playgroud)
infix operator >>> : RangeFormationPrecedence
func >>><Bound>(maximum: Bound, minimum: Bound)
-> ReversedRandomAccessCollection<CountableRange<Bound>>
where Bound : Comparable & Strideable {
return (minimum..<maximum).reversed()
}
Run Code Online (Sandbox Code Playgroud)
infix operator >>> : RangeFormationPrecedence
func >>><Bound>(maximum: Bound, minimum: Bound)
-> ReversedRandomAccessCollection<Range<Bound>>
where Bound : Strideable {
return (minimum..<maximum).reversed()
}
Run Code Online (Sandbox Code Playgroud)
看来这个问题的答案在我们通过测试版进展时有所改变.从beta 4开始,by()函数和ReversedRange类型都已从语言中删除.如果您想要制作相反的范围,您的选项现在如下:
1:创建前向范围,然后使用该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
}
Run Code Online (Sandbox Code Playgroud)
2:使用stride()beta 4中添加的新功能,其中包括指定起始和结束索引的函数,以及要迭代的数量.
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
}
Run Code Online (Sandbox Code Playgroud)
请注意,我在这篇文章中也包括了新的独家范围操作符...被替换为..<.
编辑:从Xcode 6 beta 5发行说明中,Apple添加了以下建议来处理此问题:
ReverseRange已被删除; 使用懒惰(x ..
这是一个例子.
for i in lazy(0...5).reverse() {
// 0, 1, 2, 3, 4, 5
}
Run Code Online (Sandbox Code Playgroud)
Xcode 7,beta 2:
for i in (1...5).reverse() {
// do something
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
25593 次 |
| 最近记录: |