ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Swift] Collection (Array, Dictionary, Set)
    Swift 2022. 2. 15. 08:34

    읎번 포슀팅에서는 Swift의 Collection에 대핮 알아볎자.

     

    Collection은 많은 데읎터듀을 묶얎서 횚윚적윌로 처늬하Ʞ 위핎 사용한닀.

     

    Swift Collection은 구조첎로 구현되얎있고, 죌로 값 형식윌로 사용한닀.

    Swift Collection에는 데읎터륌 순서대로 저장하는 ë°°ì—Ž (Array), 킀와 값을 하나의 쌍윌로 저장하는 ë”•셔너ëЬ (Dictionary), 집합 연산을 제공하고 고유 값듀의 순서가 지정되지 않는 ì§‘í•© (Set) ìŽ 있닀.

     

     

    컬렉션의 가변성은 컬렉션에 저장된 요소듀에게 영향을 죌지 않는닀.

    따띌서 불변 컬렉션 (let 킀워드륌 사용하여 선얞한 컬렉션)에 가변적읞 요소가 저장되얎있을 겜우, 요소륌 새롭게 추가하거나 삭제하는 것은 불가능하지만 요소륌 수정하는 것은 가능하닀.

    반멎 가변 컬렉션 (var 킀워드륌 사용하여 선얞한 컬렉션)에 불변적읞 요소가 저장되얎있을 겜우, 요소륌 새롭게 추가하거나 삭제하는 것은 가능하지만 요소륌 수정하는 것은 불가능하닀.

     

     

     

    읎제 각각의 특징에 대핎서 알아볎도록 하자.

     

     

    1. Array (ë°°ì—Ž)

    배엎을 생성하고 선얞하는 방법은 아래와 같닀.

    // #1. ë°°ì—Ž 늬터럎로 정수 ë°°ì—Ž 선얞하Ʞ
    let nums = [1, 2, 3]
    
    // #2. 빈 ë°°ì—Ž 만듀Ʞ (빈 늬터럎 -> 타입 얎녞테읎션 필수)
    let emptyArray : [Int] = []
    
    // #3. 생성자 사용핎서 만듀Ʞ (정식 묞법)
    let emptyArray2 = Array<Int>()
    
    // #4. 닚축 묞법
    let emptyArray3 = [Int]()
    
    // #5. ë°°ì—Ž 만든 후 Ʞ볞값윌로 채우Ʞ
    // 첫번짞 파띌믞터: ë°°ì—Ž 채욞 Ʞ볞값, 두번짞 파띌믞터: ë°°ì—Ž 채욞 요소의 숫자
    let zeroArray = [Int](repeating: 0, count: 10) // 0읎 10개 채워진 int ë°°ì—Ž

     

    배엎은 데읎터륌 순서대로 저장하는 Ordered Collection읎닀.

    ë°°ì—Ž 낎에 저장되는 데읎터의 자료형은 몚두 같아알하고 (Single Type), 배엎의 자료형은 직접 명시하여 선얞하거나 ë°°ì—Ž 생성 시점에 요소의 자료형을 통핎 결정된닀.

     

    Swift의 배엎은 Generic Collection읎닀. 귞렇Ʞ 때묞에 몚든 타입에서 사용할 수 있는 것읎닀.

     

    ë°°ì—Ž 낎에 저장되는 요소듀의 값은 쀑복읎여도 상ꎀ읎 없닀. 

    배엎의 읞덱슀는 0부터 시작하는 정수 읞덱슀읎고 (0-based Index), 저장되는 순서에 따띌 자동윌로 지정된닀.

    0-based Index륌 사용하Ʞ 때묞에 요소에 접귌할 때에는 읞덱슀륌 사용하거나, subscript 묞법을 사용하여 접귌하멎 된닀.

     

     

     

     

     

    찞고로, startIndex는 비얎있지 않은 배엎의 첫번짞 요소의 읞덱슀륌 의믞한닀.

     

     

    여Ʞ서 죌의핎알할 것읎 있닀.

    endIndex띌고 하멎 바로 마지막 요소의 읞덱슀띌고 생각하Ʞ 쉬욎데, endIndex는 마지막 요소의 읞덱슀가 아닌 ë§ˆì§€ë§‰ 요소의 닀음 읞덱슀륌 의믞한닀.

    따띌서 마지막 요소의 읞덱슀륌 알고 싶을 겜우, index(before:) 메소드륌 읎용핎알한닀.

     

     

    또한 first, last 속성을 읎용하멎 배엎의 첫번짞 요소와 마지막 요소륌 Optional String윌로 늬턎핎쀀닀.

     

    배엎의 성능은 크게 두 가지 요읞에 따띌 결정된닀.

    첫번짞 요읞은 ì‚œìž… 위치읎닀. 배엎의 끝에 요소륌 추가할 때에는 배엎의 크Ʞ와 상ꎀ 없읎 음정 시간 동안 수행된닀.

    하지만 배엎의 특정 위치 (예: 배엎의 가욎데)에 요소륌 추가할 때에는 더 많은 시간읎 소요된닀.

    ë°°ì—Ž 요소가 쀑간에 삜입되멎, ê·ž 뒀에 있는 몚든 요소듀읎 읞덱슀 1만큌 뒀로 읎동핎알한닀. 귞렇Ʞ 때묞에 배엎의 요소 수가 2배가 된닀멎 삜입하는데 소요되는 시간도 2배가 된닀.

    두번짞 요읞은 ë°°ì—Žì˜ 크Ʞ읎닀. 몚든 배엎은 요소륌 저장하Ʞ 위핎 음정량의 메몚늬륌 예앜핎둔닀.

    만앜 읎믞 최대 용량읎 된 배엎에 새로욎 요소륌 추가하렀고 할 겜우, 배엎은 더 큰 메몚늬 영역을 할당하고, 핎당 요소륌 새로욎 저장공간에 복사한닀. Swift 표쀀 띌읎람러늬는 저장공간읎 부족하고, 복사가 필요할 때에만 용량을 슝가시킀게 핚윌로썚 여Ʞ에 소요되는 시간을 최소화하도록 했닀.

     

     

     

     

    배엎에 요소륌 추가할 때에는 append(_:) ë©”소드 또는 append(contentsOf:) ë©”소드륌 사용한닀.

    append(_:) 메소드는 하나의 요소만 추가할 때, append(contentsOf:) 메소드는 여러 개의 요소륌 한번에 추가할 때 사용한닀.

     

    배엎의 쀑간에 요소륌 추가할 때에는 insert(_:at:) ë©”소드 또는 insert(contentsOf:at:) ë©”소드륌 사용한닀.

    insert(_:at:) 메소드는 특정 위치에 요소륌 추가할 때, insert(contentsOf:at:) 메소드는 배엎의 특정 위치에 2개 읎상의 요소륌 추가할 때 사용한닀.

     

     

    배엎의 요소륌 수정할 때에는 subscript륌 읎용하여 범위륌 통핎 수정하거나 메소드륌 읎용하여 수정하멎 된닀.

     

    subscript륌 읎용하여 수정하Ʞ

     

     

    replaceSubrange(_:with:) ë©”소드는 파띌믞터로 전달된 범위의 요소륌 전달된 컬렉션윌로 변겜한닀.

     

    replaceSubrange 메소드륌 읎용하여 수정하Ʞ

     

     

     

     

     

     

    배엎의 특정 위치에 졎재하는 요소륌 삭제할 때에는 remove(at:) ë©”소드륌 사용하는데, 읎 메소드는 전달된 읞덱슀의 요소륌 삭제한 후에 삭제된 요소의 값을 늬턎핎쀀닀.

     

    배엎의 첫번짞 요소륌 삭제할 때에는 removeFirst() ë©”소드륌 사용하는데, 읎 메소드도 첫번짞 요소륌 삭제하고 삭제된 요소의 값을 늬턎핎쀀닀.

     

     

    배엎의 제음 앞에서부터 원하는 갯수만큌의 요소륌 삭제할 겜우, removeFirst(_:) ë©”소드륌 읎용한닀. 

     

     

     

     

     

    배엎의 마지막 요소륌 삭제할 때에는 removeLast() ë©”소드륌 읎용하는데, 마지막 요소륌 삭제하고 삭제된 요소의 값을 늬턎핎쀀닀.

    배엎의 마지막 요소로부터 원하는 갯수만큌의 요소륌 삭제할 겜우에는 removeLast(_:) ë©”소드륌 읎용한닀.

     

     

     

    배엎의 요소륌 한번에 몚두 삭제할 겜우, removeAll(keepingCapacity:) ë©”소드륌 사용하멎 된닀.

    keepingCapacity는 Boolean 값윌로, Ʞ볞값은 false읎닀. 요소륌 몚두 삭제하멎 배엎읎 찚지하던 메몚늬 공간도 몚두 제거된닀.

    반멎 keepingCapacity의 Boolean 값읎 true띌멎, 요소륌 몚두 삭제한 후에도 배엎읎 찚지하던 메몚늬 공간읎 귞대로 유지된닀.

     

    ë°°ì—Ž 쀑간의 요소륌 삭제할 겜우, 뒀에 저장된 요소듀읎 앞윌로 읎동하고 읞덱슀도 몚두 업데읎튞되는데, 였버헀드가 발생하Ʞ 때묞에 되도록읎멎 배엎의 마지막에서 요소륌 추가하거나 삭제하는 것읎 좋닀.

     

    위의 메소드듀을 사용하여 배엎의 요소듀을 삭제할 때에는, 배엎읎 비얎있얎서는 안된닀. 

     

     

    하지만 popLast() ë©”소드륌 사용하멎, 배엎읎 비얎있을 때에는 nil을 늬턎하Ʞ 때묞에 안전하닀.

     

     

     

    또한 특정 범위의 배엎의 요소륌 삭제할 때에는 subscript륌 읎용하여 삭제하고자 하는 범위에 빈 배엎을 전달하여 삭제하거나, removeSubrange(_:) ë©”소드륌 읎용하여 삭제하멎 된닀.

     

     

    귞늬고 배엎을 정렬할 때에는 sorted() ë©”소드와 sort() ë©”소드륌 읎용한닀.

    sorted() 메소드는 정렬된 새로욎 배엎을 늬턎한닀. 슉, 원볞 배엎은 변핚읎 없닀.

    반멎 sort() 메소드는 원볞 배엎을 직접 정렬한닀. 

     

     

    배엎은 ë°°ì—Ž 간에 비교할 때 요소의 동음성뿐만 아니띌 요소의 순서도 고렀한닀.

     

    2. Dictionary (딕셔너늬)

     

    딕셔너늬륌 생성하고 선얞하는 방법은 아래와 같닀.

    // #1. 늬터럎로 딕셔너늬 생성
    var num = ["1": "One", "2": "Two", "3": "Three", "4": "Four", "5": "Five"]
    
    // #2. 빈 딕셔너늬 생성 -> Type Annotation 필수!
    let emptyDict: [String: String] = [:]
    
    // #3. 생성자 사용핎서 빈 딕셔너늬 생성 (닚축 묞법)
    let emptyDict2 = [String: String]()
    
    // #4. 생성자 사용핎서 빈 딕셔너늬 생성 (정식 묞법)
    let emptyDict3 = Dictionary<String, String>()

     

     

    딕셔너늬는 í‚€ì™€ 값 (key, value) ì„ 하나의 쌍윌로 저장하는 Unordered Collection읎닀.

    Unordered Collection읎Ʞ 때묞에 순서가 볎장되지 않고, value에 접귌할 때에는 key륌 통핎서 접귌핎알한닀.

    만앜 전달된 킀가 없는 겜우에는 nil을 늬턎한닀.

     

     

    귞늬고 전달된 킀가 없을 때, Ʞ볞값을 늬턎하도록 Ʞ볞값을 지정하는 것도 가능하닀.

     

     

    딕셔너늬는 순서가 없Ʞ 때묞에 배엎곌 달늬 요소가 특정 위치에 삜입되거나, 삭제되는 것에 대핮 걱정할 필요가 없닀. 따띌서 삜입/삭제하는데 드는 시간은 항상 음정하닀. íŠ¹ì • 요소륌 조회하는데 소요되는 시간도 배엎볎닀 빠륎닀. 

     

    딕셔너늬에서 key는 유음핎알하고 value는 쀑복되얎도 상ꎀ읎 없닀. 

     

    딕셔너늬는 Single Type윌로, key와 value의 자료형은 각각 몚두 같아알 한닀.

     

    딕셔너늬에 새로욎 요소륌 추가할 때에는 key 값을 읎용하여 저장한닀.

     

    만앜 읎믞 졎재하는 킀륌 또 추가할 겜우에는, 값읎 새롭게 추가되는 것읎 아니띌 Ʞ졎에 졎재하던 킀에 저장된 값읎 교첎된닀.

     

     

    닀시 정늬핎볎멎!

    킀륌 읎용하여 요소륌 추가할 때, 킀가 졎재하지 않을 때에는 새로욎 요소륌 추가 (Insert)하고, 킀가 졎재할 때에는 Ʞ졎 값을 교첎 (Update)한닀. 읎륌 Upsert ëŒê³ ë„ 한닀.

     

     

     

    딕셔너늬에서 특정 킀에 핎당하는 값을 제거할 때에는 removeValue(forKey:) ë©”소드륌 읎용한닀.

    읎 메소드륌 사용하멎, 킀에 핎당하는 값읎 제거된 후 킀에 핎당하는 값읎 늬턎된닀.

    만앜 졎재하지 않는 킀륌 삭제하렀고 하멎 nil읎 출력된닀.

     

    딕셔너늬의 몚든 킀와 요소륌 삭제할 때에는 removeAll() ë©”소드륌 읎용하멎 된닀.

     

     

    또한 딕셔너늬는 Unordered Collection읎Ʞ 때묞에 딕셔너늬 간에 비교할 때 순서륌 상ꎀ하지 않고 비교한닀.

    따띌서 저장되얎있는 킀와 값만 동음하닀멎 같은 딕셔너늬로 판닚한닀.

     

    아래 예시륌 볎멎 num곌 anotherNum 딕셔너늬는 같은 딕셔너늬임을 알 수 있닀.

     

     

     

    3. Set (집합)

    Set은 Unordered Collection읎고, 읞덱슀 또한 사용하지 않는닀.

    Set을 생성하고 선얞하는 방법은 닀음곌 같닀.

    var set1: Set<String> = Set<String>()
    var set2: Set<String> = []
    
    var nums: Set<Int> = [1, 2, 3, 4, 5, 6]

     

    Set을 ì„ ì–ží•  때에는 반드시 Type Annotation을 핎죌얎알한닀. 귞렇지 않윌멎 형식 추론에서 배엎로 추론하Ʞ 때묞에 죌의하도록 하자.

     

     

    볎통 정렬 순서볎닀 검색 순서가 쀑요할 때 ë°°ì—Ž 대신에 사용하며, 배엎곌 달늬 ì€‘복을 허용하지 않는닀.

    따띌서 쀑복읞 값듀을 저장하멎 저절로 쀑복 값듀읎 제거된닀.

     

    동음한 자료형의 요소만 저장하고 (Single Type), 저장하는 값은 유음핎알한닀. (Single Value)

     

    Set에 요소륌 추가할 때에는 insert(_:) ë©”소드 또는 update(with:) ë©”소드륌 사용한닀.

    insert(_:) 메소드륌 사용할 때 ìŽë¯ž 졎재하는 값을 닀시 추가하렀고 하멎, 추가되지 않고 묎시된닀.

     

    update(with:) 메소드는 전달된 값을 새로욎 요소로 추가핎쀀닀.

    전달된 값읎 Ʞ졎에 졎재하지 않던 새로욎 값읎띌멎 정상적윌로 추가가 완료되고 nil을 늬턎한닀.

    읎믞 졎재하던 값읎띌멎 Ʞ졎 요소륌 새로욎 값윌로 대첎하고 ê·ž 값을 Optional로 늬턎핎쀀닀.

     

     

    요소륌 삭제할 때에는 remove(_:) ë©”소드륌 읎용한닀. 

    요소가 정상적윌로 삭제되멎 삭제한 요소륌 늬턎하고, 졎재하지 않는 요소륌 삭제하렀고 하멎 nil을 늬턎한닀.

     

    귞늬고 Set의 몚든 요소륌 삭제할 때에는 removeAll() ë©”소드륌 읎용하멎 된닀.

     

     

    Set은 Unordered Collection읎므로 Set끌늬 비교할 때 요소의 동음성만 고렀하여 판닚한닀.

    만앜 요소륌 순서대로 비교하고 싶닀멎 elementsEqual 메소드륌 사용하멎 된닀.

     

     

     

    Set은 닀양한 집합 메소드륌 제공핎죌는데, 자섞한 낎용은 아래 Apple 공식묞서륌 찞고하도록 하자.

     

    Apple Developer Documentation

     

    developer.apple.com

     

    'Swift' 칎테고늬의 닀륞 Ꞁ

    [Swift] CGFloat  (0) 2022.02.15
    [Swift] Enumeration (엎거형), Raw Value (원시값)  (0) 2022.02.15
    [Swift] Tuples  (0) 2022.02.15
    [Swift] Closure, Syntax Optimization  (0) 2022.02.15
    [Swift] Function - 3 (Implicit Return, Function Notation, Function Types)  (0) 2022.02.15

    댓Ꞁ

Designed by Tistory.