놀이터에서 for 루프를 사용하면 for 루프의 첫 번째 매개 변수가 가장 높은 값으로 변경 될 때까지 모든 것이 잘 작동했습니다. (내림차순으로 인용)
이것이 버그입니까? 다른 사람이 있습니까?
for index in 510..509
{
var a = 10
}
실행될 반복 횟수를 표시하는 카운터는 계속 똑딱 거립니다.
놀이터에서 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
어떻게 작동하는지 보려면 편집 기록을 확인하십시오.
5.stride(to: 1, by: -1)
과 같습니다.5.stride(through: 1, by: -1)
:
암시 적으로 아래쪽으로 반복하여 루프를 건너 뛸 것이라고 생각했을 때 루프가 실행되는 경우 가 종종 있습니다. 대화식 사용에는 매우 편리하지만 스크립트에서 오류가 발생하기 쉬우므로 스타일 가이드가 사용하지 않는 것이 좋습니다 .
뒤로 반복하는 범위에 역 기능을 적용하십시오.
대한 스위프트 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
}
reversed
그래도 컬렉션을 복사 할 수 있습니다. 적어도, 그것이에 대한 문서를 이해하는 방법입니다 Data
.
스위프트 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
to
와 through
차이점에 유의하십시오 .
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
@matt는 자신의 역 연산자를 정의하고 호출 하는 흥미로운 솔루션을 가지고 있습니다 >>>
. 정의하는 데 많은 코드가 필요하지 않으며 다음과 같이 사용됩니다.
for index in 5>>>0 {
print(index)
}
// 4
// 3
// 2
// 1
// 0
Swift 5를 사용하면 필요에 따라 다음 네 가지 놀이터 코드 예제 중 하나를 선택 하여 문제를 해결할 수 있습니다.
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
*/
sequence(first:next:)
기능 사용스위프트 표준 라이브러리는 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
*/
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)
}
배열 ( 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
값을 쉽게 역전시키기 위해 reversed () 메소드를 사용할 수 있습니다.
var i:Int
for i in 1..10.reversed() {
print(i)
}
reversed () 메소드는 값을 반대로합니다.