development

신속하게 for 루프를 역순으로 반복하는 방법은 무엇입니까?

big-blog 2020. 5. 26. 19:02
반응형

신속하게 for 루프를 역순으로 반복하는 방법은 무엇입니까?


Playground에서 for 루프를 사용하면 for 루프의 첫 번째 매개 변수가 가장 높은 값으로 변경 될 때까지 모든 것이 잘 작동했습니다. (내림차순으로 인용)

이것이 버그입니까? 다른 사람이 있습니까?

for index in 510..509
{
    var a = 10
}

실행할 반복 횟수를 표시하는 카운터는 계속 똑딱 거립니다.

여기에 이미지 설명을 입력하십시오


: 엑스 코드 6 베타 4는 하나 이상의 다른 단계의 범위에서 반복하는 두 가지 기능을 추가 stride(from: to: by:)배타적 범위로 사용되며, stride(from: through: by:)포괄적 인 범위로 사용된다.

범위를 역순으로 반복하려면 다음과 같이 사용할 수 있습니다.

for index in stride(from: 5, to: 1, by: -1) {
    print(index)
}
//prints 5, 4, 3, 2

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

이들 중 어느 것도 Range멤버 함수 가 아닙니다 . 그것들은 구조체와 다르게 정의되는 구조체 StrideTo또는 StrideThrough구조체 를 반환하는 전역 함수입니다 Range.

이 답변의 이전 버전은 베타 4에서 제거 된 구조체 by()멤버 함수를 사용했습니다.이 기능이 Range어떻게 작동하는지 보려면 편집 기록을 확인하십시오.


뒤로 반복하는 범위에 역 기능을 적용하십시오.

대한 스위프트 1.2 및 이전 버전 :

// Print 10 through 1
for i in reverse(1...10) {
    println(i)
}

또한 반 개방 범위에서도 작동합니다.

// Print 9 through 1
for i in reverse(1..<10) {
    println(i)
}

참고 : reverse(1...10)유형의 배열을 생성 [Int]하므로 작은 범위에는 적합하지만 lazy아래 표시된대로 사용하거나 stride범위가 큰 경우 허용되는 답변을 고려하는 것이 좋습니다 .


큰 배열을 만들지 않으려면와 lazy함께 사용하십시오 reverse(). 다음 테스트는 놀이터에서 효율적으로 실행되어 1 조 개의 배열을 만들지 않음을 보여줍니다 Int!

테스트:

var count = 0
for i in lazy(1...1_000_000_000_000).reverse() {
    if ++count > 5 {
        break
    }
    println(i)
}

대한 스위프트 2.0 엑스 코드 7 :

for i in (1...10).reverse() {
    print(i)
}

Swift 2.0에서는 (1...1_000_000_000_000).reverse()유형 ReverseRandomAccessCollection<(Range<Int>)>이이므로 다음과 같이 작동합니다.

var count = 0
for i in (1...1_000_000_000_000).reverse() {
    count += 1
    if count > 5 {
        break
    }
    print(i)
}

들어 스위프트 3.0 reverse() 로 이름이 바뀌 었습니다 reversed():

for i in (1...10).reversed() {
    print(i) // prints 10 through 1
}

스위프트 3 업데이트

아래의 답변은 사용 가능한 옵션에 대한 요약입니다. 귀하의 필요에 가장 적합한 것을 선택하십시오.

reversed: 범위 내의 숫자

앞으로

for index in 0..<5 {
    print(index)
}

// 0
// 1
// 2
// 3
// 4

뒤로

for index in (0..<5).reversed() {
    print(index)
}

// 4
// 3
// 2
// 1
// 0

reversed:의 요소 SequenceType

let animals = ["horse", "cow", "camel", "sheep", "goat"]

앞으로

for animal in animals {
    print(animal)
}

// horse
// cow
// camel
// sheep
// goat

뒤로

for animal in animals.reversed() {
    print(animal)
}

// goat
// sheep
// camel
// cow
// horse

reversed: 색인이있는 요소

컬렉션을 반복 할 때 인덱스가 필요할 때가 있습니다. 이를 위해 enumerate()튜플을 반환하는을 사용할 수 있습니다 . 튜플의 첫 번째 요소는 색인이고 두 번째 요소는 객체입니다.

let animals = ["horse", "cow", "camel", "sheep", "goat"]

앞으로

for (index, animal) in animals.enumerated() {
    print("\(index), \(animal)")
}

// 0, horse
// 1, cow
// 2, camel
// 3, sheep
// 4, goat

뒤로

for (index, animal) in animals.enumerated().reversed()  {
    print("\(index), \(animal)")
}

// 4, goat
// 3, sheep
// 2, camel
// 1, cow
// 0, horse

Ben Lachman이 그의 답변 에서 언급했듯이 (색인 번호를 높이는 것 .enumerated().reversed()보다는) 오히려하기를 원할 .reversed().enumerated()것입니다.

보폭 : 숫자

보폭은 범위를 사용하지 않고 반복하는 방법입니다. 두 가지 형태가 있습니다. 코드 끝의 주석은 범위 버전이 무엇인지 보여줍니다 (증분 크기가 1이라고 가정).

startIndex.stride(to: endIndex, by: incrementSize)      // startIndex..<endIndex
startIndex.stride(through: endIndex, by: incrementSize) // startIndex...endIndex

앞으로

for index in stride(from: 0, to: 5, by: 1) {
    print(index)
}

// 0
// 1
// 2
// 3
// 4

뒤로

증분 크기를 변경하면 -1뒤로 이동할 수 있습니다.

for index in stride(from: 4, through: 0, by: -1) {
    print(index)
}

// 4
// 3
// 2
// 1
// 0

tothrough차이점에 유의하십시오 .

보폭 : SequenceType의 요소

2 씩 증가하여 앞으로

let animals = ["horse", "cow", "camel", "sheep", "goat"]

2이 예에서는 다른 가능성을 보여주기 위해 사용 하고 있습니다.

for index in stride(from: 0, to: 5, by: 2) {
    print("\(index), \(animals[index])")
}

// 0, horse
// 2, camel
// 4, goat

뒤로

for index in stride(from: 4, through: 0, by: -1) {
    print("\(index), \(animals[index])")
}

// 4, goat
// 3, sheep 
// 2, camel
// 1, cow  
// 0, horse 

노트


스위프트 4 이후

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

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

Swift 2.0 이상에서는 범위 콜렉션에 역을 적용해야합니다

for i in (0 ..< 10).reverse() {
  // process
}

Swift 3.0에서는 .reversed ()로 이름이 변경되었습니다.


Swift 5를 사용하면 필요에 따라 다음 네 가지 놀이터 코드 예제 중 하나를 선택 하여 문제를 해결할 수 있습니다.


#1. ClosedRange reversed()방법을 사용하여

ClosedRange라는 메소드가 reversed()있습니다. reversed()메소드에는 다음과 같은 선언이 있습니다.

func reversed() -> ReversedCollection<ClosedRange<Bound>>

컬렉션의 요소를 역순으로 나타내는 뷰를 반환합니다.

용법:

let reversedCollection = (0 ... 5).reversed()

for index in reversedCollection {
    print(index)
}

/*
Prints:
5
4
3
2
1
0
*/

대안으로 다음 Range reversed()방법 을 사용할 수 있습니다 .

let reversedCollection = (0 ..< 6).reversed()

for index in reversedCollection {
    print(index)
}

/*
Prints:
5
4
3
2
1
0
*/

# 2. sequence(first:next:)기능 사용

Swift Standard Library는라는 기능을 제공합니다 sequence(first:next:). sequence(first:next:)다음과 같은 선언이 있습니다.

func sequence<T>(first: T, next: @escaping (T) -> T?) -> UnfoldFirstSequence<T>

first지연 응용 프로그램으로 구성 되고 반복 되는 시퀀스를 반환합니다 next.

용법:

let unfoldSequence = sequence(first: 5, next: {
    $0 > 0 ? $0 - 1 : nil
})

for index in unfoldSequence {
    print(index)
}

/*
Prints:
5
4
3
2
1
0
*/

#삼. stride(from:through:by:)기능 사용

Swift Standard Library는라는 기능을 제공합니다 stride(from:through:by:). stride(from:through:by:)다음과 같은 선언이 있습니다.

func stride<T>(from start: T, through end: T, by stride: T.Stride) -> StrideThrough<T> where T : Strideable

시작 값부터 끝 값을 포함하여 지정된 양만큼 단계별로 시퀀스를 반환합니다.

용법:

let sequence = stride(from: 5, through: 0, by: -1)

for index in sequence {
    print(index)
}

/*
Prints:
5
4
3
2
1
0
*/

대안으로 다음을 사용할 수 있습니다 stride(from:to:by:).

let sequence = stride(from: 5, to: -1, by: -1)

for index in sequence {
    print(index)
}

/*
Prints:
5
4
3
2
1
0
*/

# 4. AnyIterator init(_:)이니셜 라이저 사용

AnyIterator이니셜 라이저가 init(_:)있습니다. init(_:)다음과 같은 선언이 있습니다.

init(_ body: @escaping () -> AnyIterator<Element>.Element?)

주어진 클로저를 next()메소드로 감싸는 반복자를 만듭니다 .

용법:

var index = 5

guard index >= 0 else { fatalError("index must be positive or equal to zero") }

let iterator = AnyIterator({ () -> Int? in
    defer { index = index - 1 }
    return index >= 0 ? index : nil
})

for index in iterator {
    print(index)
}

/*
Prints:
5
4
3
2
1
0
*/

필요한 경우 확장 메소드를 작성하고 Int반복자를 랩핑하여 이전 코드를 리팩터링 할 수 있습니다 .

extension Int {

    func iterateDownTo(_ endIndex: Int) -> AnyIterator<Int> {
        var index = self
        guard index >= endIndex else { fatalError("self must be greater than or equal to endIndex") }

        let iterator = AnyIterator { () -> Int? in
            defer { index = index - 1 }
            return index >= endIndex ? index : nil
        }
        return iterator
    }

}

let iterator = 5.iterateDownTo(0)

for index in iterator {
    print(index)
}

/*
Prints:
5
4
3
2
1
0
*/

스위프트 4 이상

    let count = 50//For example
    for i in (1...count).reversed() {
        print(i)
    }

스위프트 4.0

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

to을 포함 시키려면 다음을 수행하십시오 .

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

배열 ( Array또는 일반적으로 any SequenceType)을 반대로 반복하려는 경우 . 몇 가지 추가 옵션이 있습니다.

먼저 reverse()배열을 정상적으로 반복 할 수 있습니다 . 그러나 enumerate()객체와 색인을 포함하는 튜플을 출력하기 때문에 많은 시간 을 사용하는 것을 선호합니다 .

여기서주의해야 할 것은 올바른 순서로 호출하는 것이 중요하다는 것입니다.

for (index, element) in array.enumerate().reverse()

내림차순으로 색인을 생성합니다 (일반적으로 예상되는 것입니다). 이므로:

for (index, element) in array.reverse().enumerate()(NSArray와 더 일치합니다 reverseEnumerator)

배열을 뒤로 이동하지만 오름차순 색인을 출력합니다.


스위프트 2.2, Xcode 7.3 (2016 년 6 월 10 일) :

for (index,number) in (0...10).enumerate() {
    print("index \(index) , number \(number)")
}

for (index,number) in (0...10).reverse().enumerate() {
    print("index \(index) , number \(number)")
}

출력 :

index 0 , number 0
index 1 , number 1
index 2 , number 2
index 3 , number 3
index 4 , number 4
index 5 , number 5
index 6 , number 6
index 7 , number 7
index 8 , number 8
index 9 , number 9
index 10 , number 10


index 0 , number 10
index 1 , number 9
index 2 , number 8
index 3 , number 7
index 4 , number 6
index 5 , number 5
index 6 , number 4
index 7 , number 3
index 8 , number 2
index 9 , number 1
index 10 , number 0

var sum1 = 0
for i in 0...100{
    sum1 += i
}
print (sum1)

for i in (10...100).reverse(){
    sum1 /= i
}
print(sum1)

while대신 C 스타일 루프 사용을 고려할 수 있습니다 . 이것은 스위프트 3에서 잘 작동합니다.

var i = 5 
while i > 0 { 
    print(i)
    i -= 1
}

값을 쉽게 역전시키기 위해 reversed () 메소드를 사용할 수 있습니다.

var i:Int
for i in 1..10.reversed() {
    print(i)
}

reversed () 메소드는 값을 반대로합니다.


이를 위해 while매우 쉬운 루프 를 사용할 수 있습니다

var i = 10
while i > 1{
   print(i)
   i = i - 1
}

그러나 여전히 루프를 사용하려면 reversed()메소드 를 사용하십시오.

for i in (1...10).reversed(){
    print(i)
}

배열이 있으면 간단하게 수행 할 수 있습니다

func reverseArray(a: [Int]) -> [Int] {
   var reverseArr = [Int]()
   for i in stride(from: a.count-1, to: -1, by: -1){
      reverseArr.append(a[i])
   }
   return reverseArr
}

참고 URL : https://stackoverflow.com/questions/24508592/how-to-iterate-for-loop-in-reverse-order-in-swift

반응형