Swift의 배열과 딕셔너리 컬렉션으로 작업하기

4 분 소요

배열(array) & 딕셔너리(dictionary): 다른 객체들의 집합을 담을 수 있는 객체


가변형 컬렉션과 불변형 컬렉션

  • 가변형(mutable) 컬렉션: 객체가 초기화된 이후 변경o, 변수(variable) 에 할당
  • 불변형(immutable) 컬렉션: 객체가 초기화된 이후에 변경x, 상수(constant) 에 할당

배열 초기화

배열: 하나의 순서 있는 컬렉션에 여러 값을 담기 위하여 특별하게 설계된 데이터 타입

  • 동일한 타입의 값들만 저장가능
  • 그러나 여러 타입이 혼합된 배열 생성도 가능
  • 배열 리터럴(array literal)
    배열을 생성할 때 값들을 갖도록 초기화
    
    var 변수명: [타입] = [값1, 값2, 값3, .....]
    
    
    var treeArray = ["Pine", "Oak", "Yew"]
    

    배열을 변수에 할당(가변형)

    let treeArray = ["Pine", "Oak", "Yew"]
    

    배열을 상수에 할당(불변형)

    • 타입 선언 방법
      • 타입 추론(type inference)
        타입을 컴파일러가 자동으로 식별
          var treeArray = ["Pine", "Oak", "Yew"]
        
      • 타입 어노테이션(type annotation)
        타입을 직접 구체적으로 지정
          var treeArray2: [String] = ["Pine", "Oak", "Yew"]
        
    • 빈 배열 생성
      반드시 값을 할당해야 할 필요x
       
       var 변수명 = [타입]()
       
       
       var priceArray = [Float]()
      
    • 지정된 디폴트 값을 미리 설정
      var nameArray = [String](repeating: "My String", count: 10)
      

      ‘My String’이라는 문자열로 배열의 각 항목이 초기화되어 10개의 항목을 가진 배열 생성

    • 기존의 배열 두개 병합
      let firstArray = ["Red", "Green", "Blue"]
      let secondArray = ["Indigo", "Violet"]
      
      let thirdArray = firstArray + secondArray
      

      배열 모두가 동일한 타입의 값을 포함하고 있다고 가정


배열로 작업하기

스위프트 코드 내에서 배열의 항목을 가지고 작업하거나 조작할 수 있도록 제공된 메서드와 프로퍼티

배열 항목 개수

하나의 배열에 들어 있는 항목들의 개수: count 프로퍼티

var treeArray = ["Pine", "Oak", "Yew"]
var itemCount = treeArray.count

print(itemCount) //3

배열이 비었는지 확인: isEmpty 프로퍼티(Boolean type)

var treeArray = ["Pine", "Oak", "Yew"]

if treeArray.isEmpty {
    // 배열이 비어 있음
}

배열 항목 접근하기

인덱스 첨자(index subscripting)을 이용하여 배열 인덱스의 항목 위치를 참조,
배열의 특정 항목에 접근 or 수정

var treeArray = ["Pine", "Oak", "Yew"]
print(treeArray[2]) //Yew

특정 인덱스 위치에 있는 값을 교체

treeArray[1] = "Redwood"

Oak -> Redwood


배열 항목 섞기와 무작위로 가져오기

항목의 순서가 무작위로 섞인 새로운 배열 반환: shuffled() 메서드

let shuffledTrees = treeArray.shuffled()

배열의 항목을 무작위로 선택하여 접근: randomElement() 메서드

let randomTree = treeArray.randomElement()

배열에 항목 추가하기

: append 메서드 or +, += 연산자

treeArray.append("Redwood")
treeArray += ["Redwood"]
treeArray += ["Redwood", "Maple", "Birch"]

항목 삽입하기와 삭제하기

특정 인덱스 위치에 삽입: insert(at:) 메서드

treeArray.insert("Maple", at: 0)

뒤에 있던 기존 항목들은 오른쪽으로 한 칸씩 이동

특정 인덱스 위치에 있는 항목 제거: remove(at:) 메서드

treeArray.remove(at: 2)

배열의 마지막 항목을 삭제: removeLast 메서드

treeArray.removeLast()

배열 반복하기

<for-in>

let treeArray3 = ["Pine", "Oak", "Yew", "Maple", "Birch", "Myrtle"]
 
for tree in treeArray3 {
    print(tree)
}

출력

Pine
Oak
Yew
Maple
Birch
Myrtle

타입이 혼합된 배열 생성하기

Any 타입: 지정된 클래스 타입이 아닌 객체를 참조하는데 사용
-> Any 객체 타입을 포함하도록 선언된 배열은 여러 타입의 항목을 담을 수 있음

let mixedArray: [Any] = ["A String", 432, 34.989]

주의사항!
배열에 대한 어떤 요소에 대해 올바르지 않은 타입으로 형 변환을 할 경우, 런타임 충돌

let mixedArray: [Any] = [1, 2, 45, "Hello"]

for object in mixedArray {
    print(object * 10) // 오류발생
}

Any 타입과 Int 타입의 곱셈 연산은 불가능 -> 다운캐스팅(downcast)

for object in mixedArray {
    print(object as! Int * 10) // 컴파일o, 충돌발생
}

“Could not cast value of type ‘Swift.String’ to ‘Swift.Int’”
배열에 있는 각 항목의 특정 타입을 식별하도록 수정이 필요


딕셔너리 초기화

딕셔너리: 순서가 없는 단일 컬렉션에 여러 값을 담기 위하여 특별하게 설계된 데이터 타입

  • 키-값(key-value) 쌍의 형태로 데이터를 저장, 관리
  • 현재는 String, Int, Double, Bool 데이터 타입만을 키로 사용
  • 딕셔너리 리터럴(dictinary literal)
    딕셔너리 생성시 값들의 컬렉션으로 초기화
     
     var 변수명: [키 타입: 값 타입] = [키1: 값1, 키2: 값2 .... ]
     
     
     var bookDict = ["100-432112" : "Wind in the Willows",
                     "200-532874" : "Tale of Two Cities",
                     "202-546549" : "Sense and Sensibility",
                     "104-109834" : "Sutter Island"]
    

    타입 추론: 스위프트 컴파일러는 딕셔너리의 키와 값 항목이 String 타입임을 결정,
    다른 타입의 키 또는 값이 삽입되는 것을 막음

     var bookDict : [String: String] =
                     ["100-432112" : "Wind in the Willows",
                      "200-532874" : "Tale of Two Cities",
                      "202-546549" : "Sense and Sensibility",
                      "104-109834" : "Sutter Island"]
    

    타입 어노테이션

    • 빈 딕셔너리 생성
         
         var 변수명 = [키 타입: 값 타입]()
         
         
         var myDictionary = [Int: String]()
      

시퀀스 기반의 딕셔너리 초기화

  • 키들과 값들을 스위프트의 zip() 함수에 전달
     let keys = ["100-432112", "200-532874", "202-546549", "104-109834"]
     let values = ["Wind in the Willows", "Tale of Two Cities", "Sense and Sensibility",
                     "Shutter Island"]
    
     let bookDict = Dictionary(uniqueKeysWithValues: zip(keys, values))
    
  • 키들과 값들을 프로그램적으로 생성
     let values = ["Wind in the Willows", "Tale of Two Cities", "Sense and Sensibility", 
                     "Shutter Island"]
    
     let bookDict = Dictionary(uniqueKeysWithValues: zip(1..., values))
    

    미리 정의된 키들의 배열이 아닌 1부터 시작하는 숫자를 키로 지정

    ==

     var bookDict = [1 : "Wind in the Willows",
                     2 : "Tale of Two Cities",
                     3 : "Sense and Sensibility",
                     4 : "Shutter Island"]
    

딕셔너리 항목 개수

: count 프로퍼티

print(bookDict.count) //4

딕셔너리 항목 접근하기와 갱신하기

  • 특정 값은 해당 키를 참조하기 위해 키 첨자 구문을 이용
    print(bookDict["200-532874"]) // Optional("Tale of Two Cities")
    

    Optional 값인 이유:
    딕셔너리에 특정 키를 통해 접근할 때 해당 키에 대응되는 value값이 존재하지 않을 수 있기 때문에 Optional 타입의 값으로 반환

  • 지정된 키에 해당하는 값이 없는 경우 디폴트값 선언
    print(bookDict["999-546547", default: "Book not found"]) //Book not found
    
  • 특정 키와 연결된 값 갱신
    bookDict["200-532874"] = "Sense and Sensibility"
    

    or

    bookDict.updateValue("The Ruins", forKey: "200-532874")
    

딕셔너리 항목 추가하기와 제거하기


딕셔너리 변수[키] = 값

bookDict["300-898871"] = "The Overlook"

새로운 키-값 쌍 추가

  • 제거
    • nil 값 할당
        bookDict["300-898871"] = nil
      
    • removeValue(forKey:) 메서드 호출
        bookDict.removeValue(forKey: "300-898871")
      

딕셔너리 반복

<for-in>

for (bookid, title) in bookDict {
    print("Book ID: \(bookid), Title: \(title)")
}

출력

Book ID: 100-432112 Title: Wind in the Willows
Book ID: 200-532874 Title: The Ruins
Book ID: 104-109834 Title: Shutter Island
Book ID: 202-546549 Title: Sense and Sensibility