[Swift] Collections

상 원·2022년 7월 4일
0

Swift

목록 보기
8/31
post-thumbnail

Swift의 Collection은 세 종류가 있음.
Set, Dictionary, Array.

Set은 unique한 값들의 unordered collection.
Dictionary는 key-value 관계를 가진 값들의 unordered collection
Array는 값들의 ordered collection

Array는 인덱스가 있으므로 ordered라고 할 수 있고, Set은 중복된 값이 없으므로 unique values, Dictionary는 두 개 값을 key-value의 관계로 묶어둔 것임.

이렇게 보면 이해하기 쉬울듯.

이 친구들은 자신들이 저장할 수 있는 값의 타입과 키에 대해 엄격하기 때문에, 다른 타입이 실수로 collection에 들어갈 수 없다.

Array

Array 선언하기

//기본형
let arr1: Array[Int] = [1,2,3]
//축약형(더 많이 사용)
let arr2: [Int] = [4,5,6]

초기값을 가진 Array 만들기

var threeDoubles = Array(repeating: 0.0, count: 3)
//threeDoubles 배열은 double 타입을 가지고, [0.0, 0.0, 0.0]의 배열임.

두 Array를 더해서 Array 만들기

var threeDoubles = Array(repeating: 0.0, count: 3)
var fourDoubles = Array(repeating: 3.3, count: 4)

var newArray = threeDoubles + fourDoubles
// newArray = [0.0, 0.0, 0.0, 3.3, 3.3, 3.3, 3.3]

호환되는 타입의 배열끼리 + 를 사용해서 이어붙일 수 있다.

Array의 수정과 접근

//count로 원소갯수 접근가능
print("The shopping list contains \(shoppingList.count) items.")
// Prints "The shopping list contains 2 items."

//isEmpty로 비어있는 배열인지 확인가능
if shoppingList.isEmpty {
    print("The shopping list is empty.")
} else {
    print("The shopping list isn't empty.")
}
// Prints "The shopping list isn't empty."

//append로 배열의 마지막 원소에 붙이기 가능
shoppingList.append("Flour")
// shoppingList now contains 3 items, and someone is making pancakes

//+=로도 append 수행가능
shoppingList += ["Baking Powder"]
// shoppingList now contains 4 items

//+=로 여러개 붙일수도 있음
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
// shoppingList now contains 7 items

//인덱스로 원소 확인 가능
var firstItem = shoppingList[0]
// firstItem is equal to "Eggs"

//인덱스로 원소 바꾸기 가능
shoppingList[0] = "Six eggs"
// the first item in the list is now equal to "Six eggs" rather than "Eggs"

//4...6처럼 범위 설정해서 인덱스 접근 가능
shoppingList[4...6] = ["Bananas", "Apples"]
// shoppingList now contains 6 items

//insert로 원하는 인덱스에 원소 집어넣기 가능
shoppingList.insert("Maple Syrup", at: 0)
// shoppingList now contains 7 items
// "Maple Syrup" is now the first item in the list

//remove로 원하는 인덱스 원소 삭제 가능
let mapleSyrup = shoppingList.remove(at: 0)
// the item that was at index 0 has just been removed
// shoppingList now contains 6 items, and no Maple Syrup
// the mapleSyrup constant is now equal to the removed "Maple Syrup" string

이 외에도 removeAll(), removeLast(), removeFirst(), removeSubrange() 등 여러 메소드들이 있음.
너무 많아서 차차 알아가보도록 하자.

Array 원소 훑어보기

Array의 원소를 하나씩 보고 싶을 때는 for...in을 사용하면 된다.

var arr1 = [1,2,3,4,5]
for item in arr1{
	print(item)
}

이걸 인덱스와 함께 보고 싶다면 enumerated() 메소드를 사용하면 된다.

var arr1 = [1,2,3,4,5]
for (index, item) in arr1.enumerated(){
	print("Item \(index+1): \(item)")
}
//Item1: 1
//Item2: 2
//Item3: 3
//Item4: 4
//Item5: 5

Sets

item의 순서가 중요하지 않고, 중복되지 않은 단 하나의 item을 가지는 것이 중요하다면 Array 대신 Set을 쓰면 된다.

Hash value for Set types

Set에 저장되려면 타입이 Hashable 해야 한다.
그 말인즉슨, 타입이 자신의 값을 hash value로 만들 수 있는 방법을 제공해야 한다는 것이다.
hash value는 Int값으로, 같다고 비교되는 모든 객체에 대해 같은 값을 가진다.
예를 들어 a==b라면, a와 b의 해시값은 같다고 할 수 있다.

스위프트의 모든 기본 타입은 Hashable하며, Set value나 Dictionary key에 쓰일 수 있다.
직접 만든 타입의 경우 Hashable 프로토콜을 따르도록 만들어주면 Set이나 Dictionary에 사용 가능하다.

Set 선언하기

Set<Element>

의 기본형을 가지며, 함축형은 없음.

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."
var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]
// favoriteGenres has been initialized with three initial items

Set이라고 명시를 하지 않으면 선언한 것을 Array와 구분할 수가 없으므로, Set 선언 시에는 타입을 적어줘야 한다. 다만 타입 추론을 통해 < Element >는 적지 않아도 된다.
이런 식으로 쓰면 됨.

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

Set의 수정과 접근

//Array와 거의 비슷한듯?
//원소의 갯수를 알수있는 count
print("I have \(favoriteGenres.count) favorite music genres.")
// Prints "I have 3 favorite music genres."

//Set이 비었는지 판단하는 isEmpty
if favoriteGenres.isEmpty {
    print("As far as music goes, I'm not picky.")
} else {
    print("I have particular music preferences.")
}
// Prints "I have particular music preferences."

//Set에 새로운 원소 삽입. insert 사용
favoriteGenres.insert("Jazz")
// favoriteGenres now contains 4 items

//Set에서 원소 삭제하기. remove 사용 Set이 해당 원소를 포함하지 않는다면 nil 반환
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."

//Set에서 원소 검색하기. 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."

Set 원소 훑어보기

Array와 마찬가지로 for...in 을 사용해서 훑어볼 수 있다.

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

Set은 unordered이므로 index에 따라 순회할 수는 없지만, sorted() 메소드를 사용하면 < 을 사용해 정렬할 수 있다.

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

Set Operations

두 개의 Set을 이용해 새로운 Set을 만드는데, 두 가지의 여러 관계를 통해 만드는 방법이 존재함.

Fundamental Set Operations

  • intersection(_:) : 두 개의 공통원소로만 새로운 Set 구성.
  • symmetricDifference(_:) : 두 개의 서로소로만 새로운 Set 구성.
  • union(_:) : 두 개의 모든 원소로 새로운 Set 구성.
  • subtracting(_:) : 특정 Set을 차집합해서 새로운 Set 구성.
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의 superset, b는 a의 subset, b와 c는 disjoint

  • isSubset(of:) : 특정 Set의 subset인지!
  • isSuperset(of:) : 특정 Set의 superset인지!
  • isDisjoint(with:) : 두 Set이 공통원소가 없는지!
  • isStrictSubset(of:), isStrictSuperset(of:) : Subset, Superset인지 확인하는데 같으면 안됨!
let houseAnimals: Set = ["🐶", "🐱"]
let farmAnimals: Set = ["🐮", "🐔", "🐑", "🐶", "🐱"]
let cityAnimals: Set = ["🐦", "🐭"]

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

Dictionary

딕셔너리는 같은 타입의 키들과 같은 타입의 값(value)들의 association이다.
순서가 없는 것도 특징!
key들은 unique한데, 이것들이 값들의 식별자가 돼 줌.
진짜 사전처럼 특정 단어의 정의를 찾아보는 느낌.

Dictionary 선언하기

//기본형
let dict1: Dictionary<Int:String> = [4:"four", 1:"one"]
//축약형
let dict2: [Int:String] = [4:"four", 1:"one"]

Dictionary 수정과 접근

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

//딕셔너리의 pair 갯수 count로 접근
print("The airports dictionary contains \(airports.count) items.")
// Prints "The airports dictionary contains 2 items."

//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."

//이런식으로 추가 가능, LHR이 key, London이 value
airports["LHR"] = "London"
// the airports dictionary now contains 3 items

//key LHR의 value 수정가능
airports["LHR"] = "London Heathrow"
// the value for "LHR" has been changed to "London Heathrow"

updateValue(_: forKey:) 메소드는 해당 키의 값을 바꾸고, 이전 값을 반환해준다. 키가 없다면 새로 생성해서 만듦.

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."

키와 값 삭제는 다음과 같다.

airports["APL"] = "Apple International"
// "Apple International" isn't the real airport for APL, so delete it
airports["APL"] = nil
// APL has now been removed from the dictionary

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."

Dictionary 훑어보기

마찬가지로 for...in 을 사용하고, (key, value)의 튜플 형태로 값이 반환된다.

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

//key와 value에도 따로 접근할 수 있다.
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

//이런 식으로 키나 값을 Array형태로 만들 수도 있다.
let airportCodes = [String](airports.keys)
// airportCodes is ["LHR", "YYZ"]

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

Set와 마찬가지로 unordered이므로 어떤 정렬형태를 갖고 싶다면 key나 value에 sorted() 메소드를 사용하면 된다.

profile
ios developer

0개의 댓글