티스토리 뷰

 

Collection Types — The Swift Programming Language (Swift 5.5)

Collection Types Swift provides three primary collection types, known as arrays, sets, and dictionaries, for storing collections of values. Arrays are ordered collections of values. Sets are unordered collections of unique values. Dictionaries are unordere

docs.swift.org

1차 수정 (2022 / 02 / 26) : 오타, 의역 및 스타일 수정, 최신 이미지로 교체

 

Collection Types

Swift는 3가지 value(값) 을 저장하기 위해 Array, Set, Dictionaries 의 3 가지 기본 컬렉션 타입을 지원합니다.

Array는 값의 정렬된 집합입니다. Set은 정렬되지 않은 고유한 값들의 집합입니다. Dictorionaries 는 key-value 형태의 정렬되지 않은 집합입니다.

 

출처 : Swift 공식 문서

 

Swift의 Array, Set, Dictorionaries는 저장할 수 있는 값과 키 타입에 대해 항상 명확히 합니다. 이를 통해 잘못된 타입의 값을 실수로 컬렉션에 집어넣을 수 없습니다. 또한 '컬렉션에서 검색해서 찾을 값'에 대한 타입을 확실히 할 수 있습니다.

 

 

Mutability of Collections(컬렉션의 가변성)

만약 Array, Set, Dictorionaries 를 만들고 변수(variable) 에 선언하면, 이 3가지 컬렉션들을 변경할 수 있습니다. 즉, 컬렉션을 만든 후 컬렉션에서 항목을 추가, 제거 또는 변경하며 컬렉션을 변경할 수 있습니다. 만약 Array, Set, Dictorionaries 를 상수(constant) 로 선언하면, 컬렉션은 바꿀 수 없습니다. 컬렉션의 크기와 내용도 변경할 수 없습니다.

 

 

컬렉션을 변경할 필요가 없는 모든 경우에 대해 상수로 컬렉션(immutable collection)을 만드는 것이 좋습니다. 그렇게 하면 코드를 추론하는 것이 더 쉬워지고 Swift 컴파일러가 사용자가 만든 컬렉션의 성능을 최적화할 수 있습니다.

 

 

 

 

 

 

Arrays (배열)

Array는 같은 타입의 값(values)들 을 정렬된 리스트에 저장합니다. 배열의 다른 위치에서 동일한 값이 여러 번 나타날 수 있습니다.

 

 

Swift 의 Array 유형은 Foundation의 NSArray 클래스와 연결되어 있습니다.

 

 

Array Type Shorthand Syntax (배열 유형 약식 구문)

Swift 배열의 형식은 Array<Element>로 작성되며, 여기서 Element는 배열이 저장할 수 있는 값의 타입입니다. 배열의 유형을 더 짧게 [Element]로 쓸 수도 있습니다. 두 형식은 기능적으로는 동일하지만, 두 번째 방식이 선호되며, 이 가이드 전체에서 배열 유형을 참조할 때 사용됩니다. (Element 는 Int, Double, String 등 자료형)

 

 

Creating an Empty Array (빈 배열 선언)

이니셜라이저 구문을 사용하여 특정 유형의 빈 배열을 만들 수 있습니다.

var someInts: [Int] = []
print("someInts is of type [Int] with \(someInts.count) items.")
// Prints "someInts is of type [Int] with 0 items."
// 빈 배열이므로 count = 0

someInts 변수 타입은 이니셜라이저 타입에서 [Int]로 추론됩니다.

 

함수 인수나 이미 선언된 변수, 상수처럼 타입 정보가 제공되는 경우 , 빈 배열 리터럴 [] 을 사용하여 빈 배열을 만들 수 있습니다.

someInts.append(3)
// someInts는 3이라는 Int 값을 하나 가지고 있다
someInts = []
// someInts는 빈 배열이지만, [Int]의 타입을 가진다.
// 그 전에 Int 타입이였으므로

 

Creating an Array with a Default Value (기본값과 함께 배열 선언)

Swift는 배열의 모든 값이 동일한 기본값으로 설정된 특정 크기의 배열을 만들기 위한 이니셜라이저도 제공합니다. 이 이니셜라이저에서 repeating 에 적절한 타입의 기본값을 지정하고 count에 반복 저장할 기본값의 개수를 지정합니다.

var threeDoubles = Array(repeating: 0.0, count: 3)
// threeDoubles 는  기본값 0.0 을 3개 가지는  [0.0, 0.0, 0.0] 이다
// 0.0 이 double 타입이므로 threeDoubles 는 [Double] 타입이다

 

 

Creating an Array by Adding Two Arrays Together (두 배열을 더해서 배열 선언)

추가 연산자(+)와 호환되는 타입이 있는 두 개의 기존 배열을 함께 추가하여 새 배열을 생성할 수 있습니다. 새 배열 타입은 함께 추가하는 두 배열 타입에서 유추됩니다. 

var threeDoubles = Array(repeating: 0.0, count: 3)
// threeDoubles 는 [0.0, 0.0, 0.0]
var anotherThreeDoubles = Array(repeating: 2.5, count: 3)
// anotherThreeDoubles 는 [2.5, 2.5, 2.5]

var sixDoubles = threeDoubles + anotherThreeDoubles
// sixDoubles 은 [Double]로 추론되고,  [0.0, 0.0, 0.0, 2.5, 2.5, 2.5] 이다.

 

 

Creating an Array with an Array Literal(배열 리터럴을 이용해 배열 선언)

하나 이상의 값을 배열 모음으로 쓰는 간단한 방법으로 배열 리터럴을 사용하여 배열을 초기화할 수도 있습니다. 배열 리터럴은 쉼표로 구분된 값 목록으로 작성되며, 대괄호 [ ] 한 쌍으로 둘러싸여 있습니다.

var shoppingList: [String] = ["Eggs", "Milk"]
// shoppingList 는 2개의 아이템으로 초기화되었다

shoppingList 변수는 [String]으로 작성되는 'string 값들의 배열' 로 선언되었습니다. String으로 선언 했기 때문에 배열에 String 타입의 값만 저장할 수 있습니다. "Eggs" 와 "Milk"  2개의 문자열 값으로 초기화되었습니다.

 

이 경우 2개의 문자열 값만 포함되어 있습니다. 이는 shoppingList 의 변수 선언과 일치하므로 "Eggs" 와 "Milk" 를 적어 초기화하는 배열 리터럴 할당이 허용됩니다.

 

Swift의 유형 추론(type inference) 덕분에 동일한 유형의 값을 포함하는 배열 리터럴로 초기화하는 경우에는 배열 유형을 쓸 필요가 없습니다. 대신 shoppingList의 초기화를 더 짧은 형식으로 작성할 수 있습니다.

var shoppingList = ["Eggs", "Milk"]
// :[String] 을 쓰지 않아도 유형 추론으로 추론해준다

 

배열 리터럴의 모든 값이 동일한 유형이기 때문에 Swift는 [String]이 shopping List에 사용할 올바른 유형이라고 추론할 수 있습니다.

 

 

 

Accessing and Modifying an Array (배열에 접근하고 수정하기)

배열의 메서드(methods)와 프로퍼티들(properties)을 사용하거나 첨자 구문(subscript syntax)을 사용하여 배열에 접근하고 수정합니다.

 

배열의 항목 수를 확인하려면 읽기 전용 count 프로퍼티를 사용합니다.

print("The shopping list contains \(shoppingList.count) items.")
// Prints "The shopping list contains 2 items."

 

 

count 프로퍼티 값이 0 인지 확인하기 위한 빠른 방법으로 Boolean 타입의 isEmpty 프로퍼티를 사용합니다. 

if shoppingList.isEmpty {
    print("The shopping list is empty.")
} else {
    print("The shopping list isn't empty.")
}
// count 가 2 이므로 else 구문의 "The shopping list isn't empty." print

 

배열의 append(_:) 메소드를 사용하여 배열의 끝에 새로운 항목을 추가할 수 있습니다.

shoppingList.append("Flour")
// shoppingList 는 "Flour"가 추가되어 ["Eggs", "Milk", "Flour"] 가 된다

 

하나 이상의 항목을 추가 할당 연산자(+=) 를 사용해 추가할 수 있습니다.

shoppingList += ["Baking Powder"]
// shoppingList ["Eggs", "Milk", "Flour", "Baking Powder"]
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
// shoppingList ["Eggs", "Milk", "Flour", "Baking Powder", "Chocolate Spread", "Cheese", "Butter"]

 

첨자구문을 사용해 값을 찾을 수 있습니다. 배열의 이름 바로 뒤에 [ ] 속에 인덱스를 전달하여 배열에서 값을 검색합니다. 

var firstItem = shoppingList[0]
// firstItem 은 shoppingList의 첫 번째 항목인 "Eggs"

배열의 순서(인덱스)는 0부터 시작합니다(1이 아님). Switt의 배열은 항상 zero-indexed 이다.

 

첨자 구문을 사용하여 지정된 인덱스의 기존 값을 변경할 수 있습니다.

shoppingList[0] = "Six eggs"
// shoppingList의 첫번째 항목은 "Six eggs"가 되었다.

첨자 구문을 사용할 경우 지정한 인덱스가 유효해야 합니다. 예를 들어, 항목을 배열 끝에 추가하기 위해 shoppingList[shoppingList.count] = "Salt"를 쓰면 런타임 오류가 발생합니다. 

 

 

또한 첨자 구문을 사용하여 기존의 항목 개수와 바꿀 항목의 개수가 다르더라도 값의 범위를 한 번에 변경할 수 있습니다. 다음은 "Chocolate Spread", "Cheese", "Butter"  3개의 항목을 "Bananas" 와 "Apples" 2개로 대체하는 예입니다.

shoppingList[4...6] = ["Bananas", "Apples"]
// shoppingList ["Six eggs", "Milk", "Flour", "Baking Powder", "Chocolate Spread", "Cheese", "Butter"]
// "Chocolate Spread", "Cheese", "Butter" 가 "Bananas", "Apples" 로 대체됨
// shoppingList ["Six eggs", "Milk", "Flour", "Baking Powder", "Bananas", "Apples"]
// shoppingList는 6 개의 항목을 가진다.

 

 

항목을 지정된 인덱스의 배열에 삽입하려면 배열의 insert (_:at:) 메서드를 호출합니다.

shoppingList.insert("Maple Syrup", at: 0)
// shoppingList ["Maple Syrup", "Six eggs", "Milk", "Flour", "Baking Powder", "Bananas", "Apples"]

 

 

insert (_:at:) 메서드에 대한 이 호출은 0의 인덱스로 표시된 shoppingList의 맨 처음에 "Maple Syrup" 값을 가진 새 항목을 삽입합니다.

마찬가지로 remove(at:) 메서드를 사용하여 배열에서 항목을 제거합니다. 이 메서드는 지정된 인덱스에서 항목을 제거하고 제거된 항목을 반환합니다(필요하지 않은 경우 반환된 값을 무시할 수 있음).

let mapleSyrup = shoppingList.remove(at: 0)
// mapleSyrup  ["Six eggs", "Milk", "Flour", "Baking Powder", "Bananas", "Apples"]

 

 

배열의 기존 범위를 벗어나는 인덱스 값에 접근하거나 수정하려고 하면 런타임 오류가 발생합니다. 인덱스를 사용하기 전에 인덱스를 배열의 count 프로퍼티와 비교하여 인덱스가 유효한지 확인할 수 있습니다. 배열이 0에서 시작하기때문에 배열에서 가장 큰 유효 인덱스는 count - 1입니다. 그러나 카운트가 0이면(배열이 비어 있음) 유효한 인덱스가 없습니다.

 

항목이 제거되면 배열의 공백이 닫히므로, 인덱스 0의 값은 다시 "Six eggs"와 같습니다.

firstItem = shoppingList[0]
// firstItem 는 "Six eggs" 이다

 

 

배열에서 마지막 항목을 제거하려면 remove(at: ) 메서드가 아닌 removeLast() 메서드를 사용하여 배열의 count 프로퍼티를 사용할 필요가 없습니다. remove(at: ) 메서드와 마찬가지로 removeLast()는 제거된 항목을 반환합니다.

let apples = shoppingList.removeLast()
// apples 에는 shoppingList 배열의 제거한 마지막 항목 값 "Apples"이 저장된다.

 

 

Iterating Over an Array (배열에서 반복)

For-in 루프를 사용하여 배열의 전체 값 집합에 대해 반복할 수 있습니다.

for item in shoppingList {
    print(item)
}
// Six eggs
// Milk
// Flour
// Baking Powder
// Bananas

 

 

각 항목의 정수 인덱스와 해당 값이 필요한 경우 enumerated() 메서드를 사용하여 배열을 반복합니다. 배열의 각 항목에 대해 enumerated() 메서드는 정수와 항목으로 구성된 튜플을 반환합니다. 정수는 0에서 시작하여 각 항목에 대해 하나씩 카운트합니다. 전체 배열에 열거하면 이러한 정수는 항목의 인덱스와 일치합니다. 반복의 일부로 튜플을 임시 상수 또는 변수로 분해할 수 있습니다.

for (index, value) in shoppingList.enumerated() {
    print("Item \(index + 1): \(value)")
}
// Item 1: Six eggs
// Item 2: Milk
// Item 3: Flour
// Item 4: Baking Powder
// Item 5: Bananas

 

 

 

 

 

Sets (집합)

집합은 순서가 정의되지 않은 컬렉션에 동일한 유형의 고유한 값을 저장합니다. 항목의 순서가 중요하지 않거나 항목이 한 번만 나타나도록 해야 할 경우 배열 대신 집합을 사용할 수 있습니다.

 

Swift의 Set 타입은 Foundation의 NSSet 클래스와 연결되어 있습니다.

 

 

 

Hash Values for Set Types(Set 타입의 해쉬 값)

타입이 집합에 저장되려면 해시 가능(hashable) 해야 합니다. 즉, 타입이 자체적으로 해시 값을 계산하는 방법을 제공해야 합니다. 해시 값은 동등하게 비교하는 모든 개체에 대해 동일한 Int 값으로, a == b일 경우 a의 해시 값은 b의 해시 값과 같습니다.

Swift의 모든 기본 타입(예: String, Int, Double, Bool)은 기본적으로 해시 가능하며 집합(set) 값 타입 또는 dictionariy 키 형식으로 사용할 수 있습니다. Enumerations에 설명된 대로 연결된 값이 없는 열거 케이스 값도 기본적으로 해시할 수 있습니다.

 

Swift 표준 라이브러리의 Hashable 프로토콜을 준수하도록 하여 사용자 정의 타입을 집합(set) 값 유형 또는 dictionariy 키 유형으로 사용할 수 있습니다. 필요한 hash(:) 메서드를 구현하는 방법에 대한 자세한 내용은 Hashable을 참조하십시오. 

 

 

 

Set Type Syntax(유형 구문 설정)

Swift 집합의 타입은 Set<Element>로 작성되며, 여기서 Elemnet 는 집합이 저장할 수 있는 타입입니다. 배열과 달리 집합에는 동일한 단축 형식이 없습니다. (무조건 Set<Element> 형식)

 

 

 

Creating and Initializing an Empty Set (빈 집합 만들고 초기화)

이니셜라이저 구문을 사용하여 특정 유형의 빈 집합을 만들 수 있습니다.

var letters = Set<Character>()
print("letters is of type Set<Character> with \(letters.count) items.")
// Prints "letters is of type Set<Character> with 0 items."

letters 변수의 유형은 이니셜라이저 유형에서 Set<Character>로 유추됩니다.

 

또는 상황에서 함수 인수, 이미 입력된 변수 또는 상수와 같이 타입 정보를 이미 제공하는 경우, 빈 배열 리터럴을 사용하여 빈 집합을 만들 수 있습니다.

letters.insert("a")
// letters 는 "a" 라는 character type을 포함한다.
letters = []
// letters 은 빈 집합이지만, 여전히 Set<Character> 타입이다.

 

 

 

Creating a Set with an Array Literal (배열 리터럴로 집합 선언)

하나 이상의 값을 집합 컬렉션으로 쓰기 위한 간단한 방법으로 배열 리터럴로 집합을 초기화할 수도 있습니다.

아래 예제에서는 문자열 값을 저장할 favoriteGenres라는 집합을 만듭니다.

var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]
// favoriteGenres 은 3개의 항목과 함께 초기화되었다.

favoriteGeneres 변수는 Set<String>으로 작성된 "String 값 집합"으로 선언됩니다. 이 특정 집합은 문자열로 값 타입을 지정했으므로 문자열 값만 저장할 수 있습니다. 여기서 favoriteGenres 집합은 배열 리터럴 내에 작성된 세 개의 문자열 값("Rock", "Classical", "Hip hop")으로 초기화됩니다.

 

배열 리터럴 [ ] 에서만 집합 형식을 유추할 수 없으므로 Set 타입을 명시적으로 선언해야 합니다. 그러나 Swift의 유형 추론 때문에 하나의 타입만 포함하는 배열 리터럴로 초기화하는 경우, 집합의 <Elements> 를 쓸 필요가 없습니다. favoriteGenres의 초기화는 다음과 같이 짧은 형식으로 작성될 수 있습니다.

var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"]

 

배열 리터럴의 모든 값이 동일한 유형이기 때문에 Swift는 Set<String>이 favoriteGenres 변수에 사용할 올바른 유형이라고 추론할 수 있습니다.

 

 

 

 

Accessing and Modifying a Set (집합에 접근하고 수정)

메소드와 프로퍼티를 통해 집합에 접근하고 수정합니다. 집합의 항목 수를 확인하려면 읽기 전용 count 프로퍼티를 사용합니다.

print("I have \(favoriteGenres.count) favorite music genres.")
// Prints "I have 3 favorite music genres."

 

count 프로퍼티가 0인지 확인하기 위한 빠른 방법으로, Boolean isEmpty 프로퍼티를 사용합니다.

if favoriteGenres.isEmpty {
    print("As far as music goes, I'm not picky.")
} else {
    print("I have particular music preferences.")
}
// count가 3 이므로 isEmpty 는 false
// Prints "I have particular music preferences."

 

새로운 항목을 추가하기 위해 집합의 insert(_:) 메소드를 사용할 수 있습니다.

favoriteGenres.insert("Jazz")
// favoriteGenres 는 이제 ["Rock", "Classical", "Hip hop", "Jazz"] 이다

 

집합의 remove(_:) 메서드를 호출하여 항목을 제거할 수 있습니다. 이 메서드는 항목이 집합의 멤버일 경우 항목을 제거하고 제거된 값을 반환하거나, 집합에 항목이 없으면 0을 반환합니다. 또는 removeAll() 메서드를 사용하여 세트의 모든 항목을 제거할 수 있습니다.

if let removedGenre = favoriteGenres.remove("Rock") {
    print("\(removedGenre)? I'm over it.")
} else {
    print("I never much cared for that.")
}
// Prints "Rock? I'm over it."

 

집합이 특정 항목을 포함하는지 확인하기 위해서 contains(_:) 메소드를 사용합니다.

if favoriteGenres.contains("Funk") {
    print("I get up on the good foot.")
} else {
    print("It's too funky in here.")
}
// Prints "It's too funky in here."

 

 

 

 

Iterating Over a Set (집합에서의 반복)

for-in 루프로 집합의 값을 반복할 수 있습니다.

for genre in favoriteGenres {
    print("\(genre)")
}
// Classical
// Jazz
// Hip hop

 

Swift의 집합 유형에 정의된 순서가 없습니다. 특정 순서로 집합의 값을 반복하려면 < 연산자를 사용하여 집합의 요소를 정렬된 배열로 반환하는 sorted() 메서드를 사용합니다. (< 연산자 이므로 크기가 작은 순서로 나온다. Stirng의 경우 알파벳 순)

for genre in favoriteGenres.sorted() {
    print("\(genre)")
}
// Classical
// Hip hop
// Jazz

 

 

 

 

Performing Set Operations (집합 작업 수행)

두 집합을 결합하거나, 두 집합의 공통 값을 확인하거나, 두 집합에 동일한 값이 모두 포함되는지, 두 집합이 똑같은 값을 모두, 일부, 0개 포함하는지 등, 기본 집합 연산을 효율적으로 수행할 수 있습니다.

 

 

Fundamental Set Operations

아래 그림은 색칠된 영역으로 표현되는 다양한 세트 연산의 결과를 보여줍니다.

출처 : Swift 공식 문서

 

  • intersection(_:) 메소드를 사용해 두 집합에 공통되는 값만을 사용해 새 집합을 만듭니다.
  • symmetricDifference(_:)  메소드를 사용해 두 집합에서 공통되는 부분을 제외하고 새 집합을 만듭니다.
  • union(_:)  메소드를 사용해 두 집합에 해당하는 모든 값을 사용하여 새 집합을 만듭니다.
  • subtracting(_:) 메소드를 사용해 a에만 있는 값을 사용하여 새 집합을 만듭니다.
let oddDigits: Set = [1, 3, 5, 7, 9]
let evenDigits: Set = [0, 2, 4, 6, 8]
let singleDigitPrimeNumbers: Set = [2, 3, 5, 7]

oddDigits.union(evenDigits).sorted()
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
oddDigits.intersection(evenDigits).sorted()
// []
oddDigits.subtracting(singleDigitPrimeNumbers).sorted()
// [1, 9]
oddDigits.symmetricDifference(singleDigitPrimeNumbers).sorted()
// [1, 2, 9]

 

 

Set Membership and Equality (집합 멤버십과 동일성)

아래 그림은 세트 간에 공유되는 요소를 나타내는 영역이 겹치는 세 집합(a, b 및 c)을 보여줍니다. a에는 b의 모든 요소가 포함되므로 집합 a는 b의 상위 집합입니다. 반대로, b의 모든 원소는 a에 의해서도 포함되기 때문에 b는 a의 부분집합입니다. 집합 b와 집합 c는 공통적인 요소를 공유하지 않기 때문에 서로 분리됩니다.

출처 : Swift 공식 문서

 

  • 등호 연산자(==)를 사용하여 두 집합에 동일한 값이 모두 포함되어 있는지 여부를 확인할 수 있습니다.
  • isSubset(:) 메소드를 사용하여 집합의 모든 값이 지정된 집합에 포함되어 있는지 여부를 확인합니다.
  • isSuperset(of:) 메소드를 사용하여 집합에 지정된 집합의 모든 값이 포함되어 있는지 여부를 확인합니다.
  • isStrictSubset(:) 또는 isStrictSuperset(:): 메소드를 사용하여 집합이 부분 집합인지 또는 상위 집합인지를 확인합니다.
  • isDisjoint(:와 분리) 방법을 사용하여 두 집합의 공통 값이 없는지 여부를 확인할 수 있습니다.

 

let houseAnimals: Set = ["🐶", "🐱"]
let farmAnimals: Set = ["🐮", "🐔", "🐑", "🐶", "🐱"]
let cityAnimals: Set = ["🐦", "🐭"]

houseAnimals.isSubset(of: farmAnimals)
// true
farmAnimals.isSuperset(of: houseAnimals)
// true
farmAnimals.isDisjoint(with: cityAnimals)
// true

 

 

 

 

 

 

Dictionaries (사전)

사전은 순서가 정의되지 않은 컬렉션에서 동일한 타입의 키와 같은 타입의 값 사이의 연결을 저장합니다. 각 값은 사전에서 해당 값에 대한 식별자 역할을 하는 고유 키(key)와 연결됩니다. 배열의 항목과 달리 사전의 항목은 지정된 순서가 없습니다. 실제 사전이 특정 단어의 정의를 찾는 데 사용되는 것과 거의 같은 방식입니다. 식별자를 기준으로 값을 찾아야 할 때 사전을 사용합니다.

 

Swift의 Dictionary 타입은 Foundation의 NSDictionary 클래스와 연결되어 있습니다.

 

 

Dictionary Type Shorthand Syntax (사전 타입 요약 및 구문)

Swift 사전 타입은 Dictionary<Key, Value>으로 작성됩니다. 여기서 Key는 사전 키로 사용할 수 있는 값 타입이고 값은 사전에서 해당 키에 대해 저장하는 값 타입입니다.

 

사전 키(Key) 타입은 집합의 값(value) 형식과 같이 해시 Hashable 프로토콜을 준수해야 합니다. (고유값을 가져야 된다)

 

사전 타입을 [Key: Value]로 짧게 작성할 수도 있습니다. Dictionary<key, value>,  [Key: Value]  두 형태가 기능적으로는 동일하지만, 더 짧은 두 번째 방식이 선호되며, 사전 타입을 언급할 때 이 안내서에서는 두 번째 방식을 사용합니다.

 

 

 

 

Creating an Empty Dictionary (빈 사전 선언)

배열과 마찬가지로, 아래과 같은 이니셜라이저 구문을 사용하여 특정 타입의 빈 사전을 만들 수 있습니다.

var namesOfIntegers: [Int: String] = [:]
// namesOfIntegers 는 빈 [Int: String] dictionary 이다

 

이 예에서는 사람이 읽을 수 있는 정수 값의 이름을 저장하기 위해 [Int: String] 유형의 빈 사전을 만듭니다. 키는 Int 타입이고 값은 String 타입입니다.

상황(context = 문맥) 에서 이미 유형 정보를 제공하는 경우, 빈 사전 리터럴을 사용하여 빈 사전을 만들 수 있습니다. 이 사전 리터럴은 [:]

namesOfIntegers[16] = "sixteen"
// namesOfIntegers 는 16 - "sixteen"이라는 1개의 key-value pair 를 가진다.
namesOfIntegers = [:]
// namesOfIntegers is  [Int: String] 타입의 빈 사전이다

 

 

 

Creating a Dictionary with a Dictionary Literal (사전 리터럴로 사전 생성)

사전 리터럴을 사용하여 사전을 초기화할 수도 있습니다. 사전 리터럴은 앞서 살펴본 배열 리터럴과 구문이 유사합니다. 사전 리터럴은 하나 이상의 키 값 쌍을 사전 모음으로 쓰는 단축 방법입니다.

키-값(key - value) 쌍은 키와 값의 조합입니다. 사전 리터럴에서 각 키-값 쌍의 키와 값은 콜론 : 으로 구분됩니다. 키-값 쌍은 쉼표로 구분된 리스트로 작성되며, 대괄호 [] 로 둘러싸여 있습니다.

 

아래 예제는 국제공항의 이름을 저장하는 사전을 만듭니다. 이 사전에서 키는 세 글자로 된 국제 항공 운송 협회 코드이며 값은 공항 이름입니다.

var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]

[String: String]으로 선언된 aiports 사전은,  "키가 String 타입이고 값이 String 타입인 사전"을 의미합니다.

 

공항 사전은 두 개의 키-값(key - value) 쌍을 포함하는 사전 리터럴로 초기화됩니다. 첫 번째 쌍은 "YYZ" 키와 "Toronto Pearson" 값을 가지고 있습니다. 두 번째 쌍은 "DUB" 키와 "Dublin" 값을 가지고 있습니다.

이 사전 리터럴에는 두 개의 문자열이 포함되어 있습니다. 문자열(String) 쌍입니다. 이 키 값 타입은 공항 변수 선언 타입(String 키만 있는 사전과 String 값만 있는 사전)과 일치하므로 두 개의 초기 항목으로 공항 사전을 초기화하는 방법으로 사전 리터럴 할당이 허용됩니다.

배열과 마찬가지로 키와 값이 일치하는 사전 리터럴로 사전을 초기화하는 경우에는 사전 타입을 작성할 필요가 없습니다. 공항의 초기화는 대신 다음과 같은 더 짧은 형태로 작성될 수 있습니다.

var airports = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]

리터럴의 모든 키는 서로 같은 타입(String)이고, 마찬가지로 모든 값도 같은 타입(String)이기 때문에 Swift는 [String: String]은 airport 사전에 사용할 올바른 유형입니다.

 

 

 

Accessing and Modifying a Dictionary(사전에 접근 및 수정)

메소드 및 프로퍼티를 사용하거나 첨자 구문(subscript)을 사용하여 사전에 접근하고 수정합니다.

배열과 마찬가지로 사전의 읽기 전용 count 프로퍼티로 항목의 수를 확인할 수 있습니다.

print("The airports dictionary contains \(airports.count) items.")
// Prints "The airports dictionary contains 2 items."

 

카운트 프로퍼티가 0인지 확인하기 위한 빠른 방법으로, Boolean isEmpty 프로퍼티를 사용합니다.

if airports.isEmpty {
    print("The airports dictionary is empty.")
} else {
    print("The airports dictionary isn't empty.")
}
// Prints "The airports dictionary isn't empty."

 

첨자 구문을 사용하여 사전에 새 항목을 추가할 수 있습니다. 적절한 타입의 새 키를 첨자 인덱스로 사용하고 적절한 타입의 새 값을 할당합니다.

airports["LHR"] = "London"
// airports dictionary 는 [String:String] 이므로
// index에 String - key 값, 우측에 String - value 값 을 넣어준다
// airports는 이제 3개의 항목을 가진다

 

첨자 구문을 사용하여 특정 키와 관련된 값을 변경할 수도 있습니다.

airports["LHR"] = "London Heathrow"
//  "LHR"의 값은 기존의 "London" 에서 "London Heathrow"로 변경되었다.

 

첨자 대신 사전의 updateValue(_:forKey:) 메소드를 사용하여 특정 키에 대한 값을 설정하거나 업데이트합니다. 위의 예제처럼 updateValue(_:forKey:) 메서드는 키가 없는 경우 키에 대한 값을 설정하거나 해당 키가 이미 있는 경우 값을 업데이트합니다. 그러나 첨자와 달리 updateValue(_:forKey:) 메서드는 업데이트를 수행한 후 이전 값을 반환합니다. 이렇게 하면 업데이트 여부를 확인할 수 있습니다.

updateValue(_:forKey:) 메서드는 사전 값 타입의 옵셔널 값을 반환합니다. 예를 들어 String 값을 저장하는 사전의 경우 메서드는 String? 또는 "옵셔널 String" 유형의 값을 반환합니다. 이 옵셔널 값에는 업데이트 전에 해당 키에 대한 이전 값이 포함되어 있고, 값이 없으면 nil이 포함됩니다.

if let oldValue = airports.updateValue("Dublin Airport", forKey: "DUB") {
    print("The old value for DUB was \(oldValue).")
}
// 옵셔널이므로 언래핑 해준다
// Prints "The old value for DUB was Dublin."

 

첨자 구문을 사용하여 사전에서 특정 키에 대한 값을 검색할 수도 있습니다. 값이 없는 키를 요청할 수 있으므로 사전의 첨자는 사전 값 유형의 옵셔널 값을 반환합니다. 사전이 요청된 키 값을 포함하는 경우 첨자는 해당 키에 대한 기존 값을 포함하는 옵셔널 값을 반환합니다. 그렇지 않으면 첨자는 nil을 반환합니다.

if let airportName = airports["DUB"] {
    print("The name of the airport is \(airportName).")
} else {
    print("That airport isn't in the airports dictionary.")
}
// airports["DUB"] 의 값이 String? 이므로 언래핑 해준다
// Prints "The name of the airport is Dublin Airport."

 

첨자 구문을 사용하여 사전에서 해당 키에 nil 값을 할당하여 키-값(key-value) 쌍을 제거할 수 있습니다.

airports["APL"] = "Apple International"
// "Apple International" 는 진짜 공항이 아니므로 제거하겠다.
airports["APL"] = nil
// APL 은 이제 사전에서 제거되었다.

 

다른 방법으로 removeValue(forKey:) 메소드를 사용하여 사전에서 키-값 쌍을 제거합니다. 이 메소드는 키-값 쌍이 존재하는 경우 해당 쌍을 제거하고 제거된 값을 반환하거나 값이 없는 경우 nil을 반환합니다.

if let removedValue = airports.removeValue(forKey: "DUB") {
    print("The removed airport's name is \(removedValue).")
} else {
    print("The airports dictionary doesn't contain a value for DUB.")
}
// Prints "The removed airport's name is Dublin Airport."

 

 

 

 

Iterating Over a Dictionary(사전에 대한 반복)

for-in 루프로 사전에서 키-값 쌍을 반복할 수 있습니다. 사전의 각 항목은 (키, 값) 튜플로 반환되며 반복의 일부로 튜플 멤버를 임시 상수 또는 변수로 분해할 수 있습니다.

for (airportCode, airportName) in airports {
    print("\(airportCode): \(airportName)")
}
// LHR: London Heathrow
// YYZ: Toronto Pearson

 

사전의 키와 값에 각각 접근하여 사전의 키 또는 값의 반복 가능한 컬렉션을 검색할 수도 있습니다.

for airportCode in airports.keys {
    print("Airport code: \(airportCode)")
}
// Airport code: LHR
// Airport code: YYZ

for airportName in airports.values {
    print("Airport name: \(airportName)")
}
// Airport name: London Heathrow
// Airport name: Toronto Pearson

 

배열 인스턴스를 사용하는 API로 사전의 키 또는 값을 사용해야 하는 경우, 키 또는 값 속성으로 새 배열을 초기화합니다.

let airportCodes = [String](airports.keys)
// airportCodes is ["LHR", "YYZ"]

let airportNames = [String](airports.values)
// airportNames is ["London Heathrow", "Toronto Pearson"]

 

Swift의 사전 타입에는 순서가 없습니다. 사전의 키나 값을 특정 순서로 반복하려면, 키(key) 나 값(value) 프로퍼티의 sorted() 메소드를 사용합니다.

 

 

 

 

 

 

Swift의 Collection Types 인 Array, Set, Dictorionaries 에 대해 공부했습니다.

전공과 SwiftUI를 공부하다보니 한동안 문법 정리할 시간이 없었네요 😥 

하루에 한 챕터는 다 못하더라도 조금씩이라도 정리해야겠습니다

긴 글 읽어주셔서 감사합니다 😊

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
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 31
글 보관함