code

Swift의 역 범위

codestyles 2020. 8. 28. 07:31
반응형

Swift의 역 범위


Swift에서 역 범위로 작업하는 방법이 있습니까?

예를 들면 :

for i in 5...1 {
  // do something
}

무한 루프입니다.

1..5대신 사용할 수 있고 계산 j = 6 - i하여 j색인으로 사용할 수 있다는 것을 알고 있습니다 . 더 읽기 쉬운 것이 있는지 궁금합니다.


최신 Swift 3 업데이트 (Swift 4에서도 작동)

reversed()범위 에서 방법을 사용할 수 있습니다.

for i in (1...5).reversed() { print(i) } // 5 4 3 2 1

또는 stride(from:through:by:)방법

for i in stride(from:5,through:1,by:-1) { print(i) } // 5 4 3 2 1

stide(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 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

다음에서도 작동합니다 Doubles.

for i in 0.5.stride(to:-0.1, by: -0.1) { print(i) }

경계에 대한 부동 소수점 비교에주의하십시오.

Swift 1.2의 이전 편집 : Xcode 6 Beta 4부터 byReverseRange 는 더 이상 존재하지 않습니다.

범위를 반전하려는 경우에는 반전 기능 만 있으면됩니다.

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
}

이것의 비대칭에 문제가 있습니다.

for i in (1..<5).reverse()

... 이와 반대로 :

for i in 1..<5 {

역방향 범위를하고 싶을 때마다 괄호를 넣어야한다는 것을 기억해야 .reverse()하고, 끝에는 엄지 손가락처럼 튀어 나와서 써야합니다 . 이것은 대칭 적으로 카운트 업 및 카운트 다운하는 C 스타일 for 루프와 비교할 때 정말 추합니다. 그래서 대신 C 스타일 for 루프를 사용하는 경향이 있습니다. 그러나 Swift 2.2에서는 C 스타일 for 루프가 사라집니다! 그래서 저는 감소하는 모든 C 스타일 for 루프를이 추악한 .reverse()구조로 교체해야했습니다. 그동안 왜 역 거리 연산자가 없는지 궁금합니다.

하지만 기다려! 이것은 Swift입니다 — 우리는 우리 자신의 연산자를 정의 할 수 있습니다 !! 여기 있습니다 :

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

This covers just the most common case that occurs in my code, but it is far and away the most common case, so it's all I need at present.

I had a kind of internal crisis coming up with the operator. I would have liked to use >.., as being the reverse of ..<, but that's not legal: you can't use a dot after a non-dot, it appears. I considered ..> but decided it was too hard to distinguish from ..<. The nice thing about >>> is that it screams at you: "down to!" (Of course you're free to come up with another operator. But my advice is: for super symmetry, define <<< to do what ..< does, and now you've got <<< and >>> which are symmetrical and easy to type.)


Swift 3 version (Xcode 8 seed 6):

infix operator >>> : RangeFormationPrecedence
func >>><Bound>(maximum: Bound, minimum: Bound) ->
    ReversedRandomAccessCollection<CountableRange<Bound>> 
    where Bound : Comparable, Bound.Stride : Integer {
        return (minimum..<maximum).reversed()
}

Swift 4 version (Xcode 9 beta 3):

infix operator >>> : RangeFormationPrecedence
func >>><Bound>(maximum: Bound, minimum: Bound)
    -> ReversedRandomAccessCollection<CountableRange<Bound>>
    where Bound : Comparable & Strideable { 
        return (minimum..<maximum).reversed()
}

Swift 4.2 version (Xcode 10 beta 1):

infix operator >>> : RangeFormationPrecedence
func >>><Bound>(maximum: Bound, minimum: Bound)
    -> ReversedRandomAccessCollection<Range<Bound>>
    where Bound : Strideable { 
        return (minimum..<maximum).reversed()
}

Swift 5 version (Xcode 10.2.1):

infix operator >>> : RangeFormationPrecedence
func >>><Bound>(maximum: Bound, minimum: Bound)
    -> ReversedCollection<Range<Bound>>
    where Bound : Strideable {
        return (minimum..<maximum).reversed()
}

It appears that the answers to this question have changed a bit as we've progressed through the betas. As of beta 4, both the by() function and the ReversedRange type have been removed from the language. If you're looking to make a reversed range, your options are now as follows:

1: Create a forward range, and then use the reverse() function to reverse it.

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: Use the new stride() functions that were added in beta 4, which includes functions to specify the starting and ending indexes, as well as the amount to iterate by.

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
}

Note that I've also included the new exclusive range operator in this post as well. .. was replaced with ..<.

Edit: From the Xcode 6 beta 5 release notes, Apple added the following suggestion for handling this:

ReverseRange has been removed; use lazy(x..

Here's an example.

for i in lazy(0...5).reverse() {
    // 0, 1, 2, 3, 4, 5
}

Xcode 7, beta 2:

for i in (1...5).reverse() {
  // do something
}

Swift 3, 4+: you can do it like this:

for i in sequence(first: 10, next: {$0 - 1}) {

    guard i >= 0 else {
        break
    }
    print(i)
}

result: 10, 9, 8 ... 0

You can customise it any way you like. For more info read func sequence<T> reference


This could be another way of doing this.

(1...5).reversed().forEach { print($0) }

Reverse() function is used for reverse number.

Var n:Int // Enter number

For i in 1...n.reverse() { Print(i) }

참고URL : https://stackoverflow.com/questions/24372559/reverse-range-in-swift

반응형