-
[Swift] - 배열 루프를 순회하는 방식(enumerated,indices,Range(0..<arr.count))iOS/SWIFT 2025. 3. 20. 20:29728x90반응형
팀원들과 코드리뷰를 하던 중 모두 배열 루프를 돌리는 방식의 차이가 모두 다르다는 것을 깨달았다.
기능적으로는 모두 같은 결과가 나오는 코드를 작성할 수는 있지만, 난 항상 이런 동일한 결과가 나오는 코드는 성능적인 차이가 있을까에 대한 고민을 많이 하는 편이다. 제목처럼 오늘은 배열 루프를 돌리는 방식(enumerated(),indices,Range(0..arr.count)에 대해서 하나씩 살펴볼 것이다.
1.Range(0..arr.count)
이렇게 보면 뭔가 어색하지만 이 방식은 다음과 같이 표현한다.
let arr = ["a", "b", "c"] for i in 0..<arr.count { print("\(i): \(arr[i])") }
기본적으로 swift에서 for문을 돌리는 정석적인 방법이다.
직관적이나, 개발자가 직접 숫자로 범위를 조작하기 때문에 작성을 실수할 가능성이 있다.
대표적으로 Index out of range 예외를 발생시킬 수 있다.
하지만 개발자가 직접 숫자로 범위를 조작할 수 있는게, 오히려 배열을 조금 더 자유롭게 컨트롤할 수 있는 장점이 될 수도 있다.
2. indices
indices는 배열의 유효한 인덱스 범위를 나타내는 Range 또는 ClosedRange 타입을 반환한다.
Swift에서 배열의 indices 프로퍼티는 Range(0..<arr.count)와 동일하다.
let arr = ["a", "b", "c"] for i in arr.indices { print("\(i): \(arr[i])") } // 출력 // 0: a // 1: b // 2: c
이것을 사용할 경우 배열의 유효한 인덱스만 제공하므로 안정성이 높다.
이 말은 즉슨, 런타임시에 오류가 나는 경우의 수가 없다는 것이다. 이 부분은 Range(0..arr.count)의 단점을 보완할 수 있다.
하지만 오히려 Range(0..arr.count)의 장점이 indices의 단점이 된다.
3. enumerated()
enumerated()는 Array를 (index, value) 튜플로 변환하여 반복하는 방식이다.
반환 타입은 EnumeratedSequence<[Element]> 으로 표기하며 내부적으로 IndexingIterator를 사용하여 효율적으로 인덱스를 추적함.
let arr = ["a", "b", "c"] for (i, value) in arr.enumerated() { print("\(i): \(value)") }
튜플에 바로 접근해 별도로 인덱싱을 할 필요가 없다는 것이 장점이고, 인덱스와 값이 동시에 필요한 경우 꼭 이 유틸리티 메서드가 필요하다.
하지만 enumerated()는 lazy로 작동하지 않는다. 이 말은 모든 요소에 대해 튜플을 생성한다는 것이다.
위에서 말한 index와 value가 모두 필요하지 않는 경우 오히려 추가적인 튜플을 생성함으로 약간의 메모리 오버헤드가 생길 수 있다는 것이다.(아주 미미한 차이다..)
📌 결론
1. 배열을 안전하게, 전부 순회해야 할 경우→ arr.indices
2. 배열의 순회의 제한을 두고 유동적으로 순회해야 할 경우 → (0..<arr.count)
3. 배열을 순회하면서 index와 value를 필요로 할 경우 → arr.enumerated()
이렇게 정리할 수 있을 것 같다.
이 외의 차이는 아직 잘 모르겠다. 추가적으로 알게된 점이 생기면 포스팅해 볼 예정이다.
참고
https://developer.apple.com/documentation/swift/string/indices-swift.property
indices | Apple Developer Documentation
The indices that are valid for subscripting the collection, in ascending order.
developer.apple.com
https://developer.apple.com/documentation/swift/array/enumerated()
enumerated() | Apple Developer Documentation
Returns a sequence of pairs (n, x), where n represents a consecutive integer starting at zero and x represents an element of the sequence.
developer.apple.com
https://developer.apple.com/documentation/swift/range
Range | Apple Developer Documentation
A half-open interval from a lower bound up to, but not including, an upper bound.
developer.apple.com
'iOS > SWIFT' 카테고리의 다른 글
[Swift] - Character와 EGC(Extended Grapheme Cluster) (0) 2025.03.14 [Swift] - mutating (0) 2024.02.06 [SWIFT] - 제네릭(Generic) (0) 2023.06.14 [SWIFT] Lazy #8 (1) 2022.12.19 [SWIFT] 타입프로퍼티 #7 (0) 2022.10.10