본문 바로가기

iOS/Swift

Swift) for - in / forEach 제대로 알고 쓰기

 

 

 

안녕하세요 :) 소들입니다 🌸

오늘은 우리가 Swift로 프로그래밍을 하다보면 정말정말 많이 쓰는

 

for - in

forEach

 

에 대해서 알아보려고 해요!!!!

이 둘의 사용법은 물론 차이점에 대해서도 알아볼 것이에요

 

보통 그냥 둘 다 Collection Type을 순회할 때 아무거나 골라서 쓰지

둘의 차이점에 대해 명확히 모르고 쓰시는 분도 있는 거 같아서..(나도 그랬음)

 

이번 포스팅을 통해 제대로 알아봅시다.. :)

모든 포스팅은 편의 말투로 합니다~!!

 

 

 

 

1. for - in

 

컬렉션에 저장된 요소 수만큼 반복되며, 저장된 요소가 루프 상수에 하나씩 들어간다

 

먼저 정의는 위와 같은데,

Collection Type에 따라 사용법을 나눠서 보여주겠음 :)

 

 

 

1-1. Array

 

 

let nums: [Int= [1234]
 
for num in nums {
    print(num)        // 1 2 3 4
}
 

 

 

자, nums란 배열이 있을 때, 위와 같이 해주면 nums의 요소 갯수만큼 반복문이 반복함!!!!

 

1번째 반복할 땐 num이란 루프 상수에 nums[0]의 값이 들어감

2번째 반복할 땐 num이란 루프 상수에 nums[1]의 값이 들어감

...

n번째 반복할 땐 num이란 루프 상수에 num[n-1]의 값이 들어감

 

이런 식으로 배열의 갯수만큼 반복하기 때문에,

for - in 반복문을 사용하여 배열의 모~든 요소에 num이란 루프 상수로 접근이 가능함!.

(여기서 num이란 루프 상수의 이름은 알아서 센스 있게 작성해주시면 됨!!)

 

만약 나는 배열의 요소를 순회하면서,

현재 반복문의 index도 알고 싶으면 어떻게 하나요!?

라고 할 경우 다음과 같이 사용할 수도 있음 :)

 

 

for (index, num) in nums.enumerated() {
    print("(index: \(index) num: \(num))")                // (index: 0 num: 1) (index: 1 num: 2) (index: 2 num: 3) (index: 3 num: 4)
}
 
for index in nums.indices {
    print("(index: \(index) num: \(nums[index]))")        // (index: 0 num: 1) (index: 1 num: 2) (index: 2 num: 3) (index: 3 num: 4)
}
 
for index in 0..<nums.count {
    print("(index: \(index) num: \(nums[index]))")        // (index: 0 num: 1) (index: 1 num: 2) (index: 2 num: 3) (index: 3 num: 4)
}
 

 

 

enumerated 메서드나 indices를 이용하거나, 직접 반복 횟수를 지정해서 받을 수도 있음!

뭐 이런 방법들도 있고 다른 방법들도 있으니,

 편한대로 쓰세용 :)

 

 

 

1-2. Dictionary

 

 

let dict: [String : String= ["A" : "Apple""B" : "Banana""C" : "Cherry"]
  
for (key, value) in dict {
    print("(\(key) : \(value))")                     // (B : Banana) (C : Cherry) (A : Apple)
}
 
for element in dict {
    print("\(element.key) : \(element.value))")      // (B : Banana) (A : Apple) (C : Cherry)
}
 

 

 

Dictionary 같은 경우, Key-Value로 저장되어 있고, 정렬되지 않는다는 특징이 있잖음!?!?

따라서 print 결과 값은 찍을 때마다 달라질 것임!!! 배열이 아니라 넣은 순서대로 정렬되지 않기 때문!

 

Dictionary의 경우, 순회하며 받는 루프 상수가 튜플(key, value) 타입

첫 번째 방법과 같이 튜플 상수를 각각 선언해서 받아도 되고,

혹은 두 번째 방법과 같이 한번에 받아서 점문법을 이용해서도 접근 가능함 :) 

보통 첫 번째 방법처럼 씁니다.. :)

 

만약, key 또는 value만 반복하고 싶다면,

 

 

for key in dict.keys {
    print(key)          // C B A
}
 
for value in dict.values.sorted() {
    print(value)        // Apple Banana Cherry
}
 

 

 

이렇게 해주면 key, value만 순회할 수 있음!!!!

참고로 정렬 함수인 sorted 함수도 둘 다 사용할 수 있음 :)

 

 

 

1-3. Set

 

 

let numsSet<Int= [1234]
 
for num in nums {
    print(num)        // 3 2 4 1
}
 

 

 

Set은 배열과 비슷하지만, 정렬되지 않고 중복 요소를 저장하지 않는 것 뿐이잖음?

따라서 for - in 문은 그냥 배열하고 동일하게 사용하면 됨!!!

다만, Dictionary와 동일하게, print 결과 값은 찍을 때마다 달라질 것

 

.

.

자 여기까지가 for - in 사용법에 대해 알아본 것이고,

이제 forEach 사용법에 대해 알아볼 것임 :)

 

 

 

 

2. forEach

 

반복 실행하려는 코드를 파라미터로 받고, 저장된 요소는 클로저 상수로 전달된다

 

forEach : 야 나는 이 Collection의 요소 갯수만큼 반복해주는 함수다?

근데 반복할 때 할 작업은 너가 클로저로 작성해서 내 파라미터로 넘겨줘라 ㅇㅋ?

Collection에 저장된 요소는 클로저 반복 실행할 때마다 클로저 상수로 넘겨줄게

 

이렇게 되는 것임!!

이렇게 이론으로 보면 어려운데, 코드로 보면 쉬우니까 코드로 봅시다 :)

 

 

 

2-1. Array

 

 

let nums: [Int= [1234]
 
nums.forEach {
    print($0)       // 1 2 3 4
}
 

 

 

이렇게 사용하면 됨 :)  이럴 경우,

내가 전달한 print 함수를 찍는 클로저를 nums 요소의 갯수(4)만큼 반복함!

 

만약 위 클로저 문법이 아직 어색하신 분이라면...

클로저, 누구냐 넌 부터 보고 오시길.....ㅎ

 

만약, for - in 처럼 나는 반복 index를 알고 싶은데!? 하면,

 

 

nums.enumerated().forEach {
    print("(index: \($0) num: \($1))")             // (index: 0 num: 1) (index: 1 num: 2) (index: 2 num: 3) (index: 3 num: 4)
}
 
nums.indices.forEach {
    print("(index: \($0) num: \(nums[$0]))")       // (index: 0 num: 1) (index: 1 num: 2) (index: 2 num: 3) (index: 3 num: 4)
}
 

 

 

for - in과 마찬가지로 enumerated 메서드나 indices를 이용하시면 됨니다 :)

근데 내가 본 바로 forEach는 반복 횟수를 제어할 수 없는 거 같은데..

맞나요..? 만약 제어하는 방법 아시는 분 댓글점 ㅜㅜ

 

 

 

2-2. Dictionary

 

for - in과 똑같으나 클로저로 넘겨준단 점만 다르니,

한번에 코딩 하겠움

 

 

let dict: [String : String= ["A" : "Apple""B" : "Banana""C" : "Cherry"]
 
dict.forEach {
    print("(\($0.key) : \($0.value))")  // (B : Banana) (C : Cherry) (A : Apple)
}
 
dict.forEach { (key, value) in
    print("(\(key) \(value))")        // (C : Cherry) (A : Apple) (B : Banana)
}
 
dict.keys.forEach {
    print($0)       // B C A
}
 
dict.values.sorted().forEach {
    print($0)       // Apple Banana Cherry
}
 

 

 

 

쨔잔 :)

 

 

 

2-3. Set

 

 

let numsSet<Int> = [1234]
 
nums.forEach {
    print($0)               // 2 3 1 4
}
 

 

 

Set은 배열과 같이 보면 되니까.. :)

그럼 forEach 사용법도 끝!!!!!!

 

 

 

 

3. for - in과 forEach의 차이점

 

자, for - in 문과 forEach의 사용법에 대해 알아봤다면!

이젠 이 둘의 차이점에 대해 알아볼 것임 :)

 

 

 

3-1. continue & break

 

먼저, 

for - in문은 우리가 직접 구현하는 "반복문"이었음!

 

하지만 forEach는 내가 반복하고 싶은 구문을

forEach라는 함수의 파라미터로 "클로저"로 작성해서 넘겨주는 것이었음!

 

그렇기 때문에,

반복문 안에서만 사용할 수 있는 continue, break

for - in 에선 사용 가능하지만, forEach에서는 불가능함

 

 

for num in nums {
    break
    continue
}
 
nums.forEach {
    break       // error!
    continue    // error!
}

 

 

그러하다 :)

forEach는 반복문이 아니라, 클로저를 파라미터로 넘겨주는 메서드라는 것을 꼭 기억하시길!

 

 

 

3-2. return 문의 영향

 

return문의 영향을 받는 것 또한 두 개가 다름!

 

 

func printForIn() {
    let nums = [123]
    
    for num in nums {
        print(num)
        return
    }
}

 

 

먼저, for - in의 경우 반복문을 돌다가 return을 만나면 함수 자체가 종료됨!!

따라서 위 함수를 실행할 경우,

 

 

 

 

한번 실행하고 함수가 return 되어 끝남

하지만 forEach 같은 경우,

 

 

func printForEach() {
    let nums = [123]
    
    nums.forEach {
        print($0)
        return
    }
}

 

 

반복문이 아닌 클로저 즉, 반복하고자 하는 내용을 익명 함수를 전달하기 때문에

return을 만난다는 것은 내가 전달한 클로저를 종료하는 것을 뜻함!!!

 

근데 뭐다? forEach는 내가 전달한 클로저를 요소 갯수 만큼이나 실행한다!

따라서, 1번째 반복 땐 1을 프린트하고 클로저를 return해버려서

바로 다음 2번째 반복 클로저가 실행되는 것임

한마디로 반복 횟수에 영향을 주지 않는다는 것!!!

때문에 결과값도

 

 

 

 

모두 잘 출력됨 :)

 

 

 

 

 

 

.

.

.

오늘은 Fast Enumeration,

즉 for-in과 forEach에 대해 알아 봤엉요:)

혹시 헷갈리는 개념이었다면 포스팅을 통해 이해에 도움이 됐기를!

나중엔 custom 자료형에 Fast Enumeration을 적용하는 방법도 포스팅 해볼게여~~

 

피드백, 추가할 점, 질문은 언제나 댓글 남겨주세요 👍

그럼 20,000

 

 

솜네일

 



Calendar
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
최근 댓글
Visits
Today
Yesterday