Swift 5년차가 이것도 몰라? (배열, 딕셔너리, 세트 완벽 이해 2탄)

작성일 :

Swift 중급자를 위한 심화 가이드: 배열, 딕셔너리, 세트 완벽 이해

Swift는 애플의 iOS, macOS, watchOS, tvOS 애플리케이션을 개발하기 위해 설계된 강력하고 직관적인 프로그래밍 언어입니다. 중급 개발자라면 배열(Array), 딕셔너리(Dictionary), 세트(Set)와 같은 기본 컬렉션 타입에 대한 기본 지식은 이미 가지고 있을 것입니다. 이번 가이드에서는 이들 컬렉션 타입을 더 효율적으로 사용하고, 고급 기능들을 활용하는 방법에 대해 다루겠습니다.

배열 (Array)

배열의 고급 사용법

배열은 동일한 타입의 값들을 순서대로 저장하는 컬렉션 타입입니다. 배열을 더 효율적으로 사용하는 방법을 알아봅시다.

배열 슬라이싱

배열의 일부를 쉽게 추출할 수 있습니다.

swift
let numbers = [1, 2, 3, 4, 5, 6]
let slice = numbers[2...4] // [3, 4, 5]

고차 함수 사용

배열에서 자주 사용하는 고차 함수 map, filter, reduce를 활용해 봅시다.

swift
let doubled = numbers.map { $0 * 2 }
let evenNumbers = numbers.filter { $0 % 2 == 0 }
let sum = numbers.reduce(0, +)

성능 최적화

배열의 성능을 최적화하기 위해 reserveCapacity 메서드를 사용할 수 있습니다. 이는 배열의 크기를 미리 할당하여 추가 작업 시 성능 저하를 방지합니다.

swift
var dynamicArray: [Int] = []
dynamicArray.reserveCapacity(1000)

딕셔너리 (Dictionary)

딕셔너리의 고급 사용법

딕셔너리는 키-값 쌍으로 데이터를 저장하는 컬렉션 타입입니다. 딕셔너리를 더 효율적으로 사용하는 방법을 알아봅시다.

딕셔너리 병합

두 딕셔너리를 병합할 때 merging 메서드를 사용할 수 있습니다.

swift
let dict1 = ["a": 1, "b": 2]
let dict2 = ["b": 3, "c": 4]
let mergedDict = dict1.merging(dict2) { (current, new) in new }

딕셔너리 필터링

딕셔너리의 특정 조건에 맞는 요소를 필터링 할 수 있습니다.

swift
let filteredDict = mergedDict.filter { $0.value > 2 }

성능 최적화

딕셔너리의 성능을 최적화하기 위해 적절한 해시 함수를 사용하는 것이 중요합니다. Swift에서는 커스텀 타입을 딕셔너리의 키로 사용할 때 Hashable 프로토콜을 준수해야 합니다.

swift
struct Person: Hashable {
    let id: Int
    let name: String
}

let peopleDict: [Person: Int] = [Person(id: 1, name: "John"): 90]

세트 (Set)

세트의 고급 사용법

세트는 고유한 값들을 저장하는 컬렉션 타입입니다. 중복된 값을 허용하지 않으며, 효율적인 집합 연산을 지원합니다.

세트 연산

세트는 합집합, 교집합, 차집합 등의 집합 연산을 효율적으로 수행할 수 있습니다.

swift
let setA: Set = [1, 2, 3, 4]
let setB: Set = [3, 4, 5, 6]

let union = setA.union(setB) // [1, 2, 3, 4, 5, 6]
let intersection = setA.intersection(setB) // [3, 4]
let difference = setA.subtracting(setB) // [1, 2]

세트 필터링

세트의 특정 조건에 맞는 요소를 필터링 할 수 있습니다.

swift
let filteredSet = setA.filter { $0 > 2 } // [3, 4]

성능 최적화

세트의 성능을 최적화하기 위해 적절한 해시 함수를 사용하는 것이 중요합니다. Swift에서는 커스텀 타입을 세트의 요소로 사용할 때 Hashable 프로토콜을 준수해야 합니다.

swift
struct CustomType: Hashable {
    let id: Int
}

let customSet: Set<CustomType> = [CustomType(id: 1), CustomType(id: 2)]

고급 활용 사례

데이터 변환

배열, 딕셔너리, 세트를 상호 변환하는 방법을 알아봅시다.

swift
let array = [("a", 1), ("b", 2), ("c", 3)]
let dict = Dictionary(uniqueKeysWithValues: array) // ["a": 1, "b": 2, "c": 3]
let set = Set(array.map { $0.1 }) // [1, 2, 3]

성능 비교

배열, 딕셔너리, 세트는 각기 다른 용도와 성능 특성을 가지고 있습니다. 예를 들어, 배열은 순서가 중요할 때 유용하고, 딕셔너리는 키-값 조회가 빠르며, 세트는 고유한 값 관리에 최적화되어 있습니다. 성능을 고려해 적절한 컬렉션 타입을 선택하는 것이 중요합니다.

비동기 프로그래밍과 컬렉션

Swift에서 비동기 작업을 처리할 때 컬렉션 타입을 효과적으로 사용하는 방법도 중요합니다. 예를 들어, 여러 비동기 작업의 결과를 배열에 저장하거나, 비동기 작업 중간에 딕셔너리를 통해 상태를 관리할 수 있습니다.

swift
func fetchData(completion: @escaping ([String: Int]) -> Void) {
    DispatchQueue.global().async {
        // 데이터 처리
        let result = ["key1": 1, "key2": 2]
        completion(result)
    }
}

fetchData { data in
    print(data) // ["key1": 1, "key2": 2]
}

결론

Swift의 배열, 딕셔너리, 세트는 매우 강력한 컬렉션 타입입니다. 중급 개발자는 이러한 컬렉션 타입을 더 효율적으로 사용하기 위해 고급 기능들을 익히고, 성능 최적화 기법을 이해해야 합니다. 이 가이드를 통해 Swift의 컬렉션 타입에 대한 심화 지식을 쌓고, 실무에서 더욱 효율적이고 강력한 코드를 작성할 수 있기를 바랍니다. Swift의 다양한 기능을 활용하여 더욱 높은 수준의 프로그래밍 스킬을 갖추길 바랍니다.