Swift Doc 톺아보기 (3) - 컬렉션

요나·2023년 5월 7일

Swift Doc 톺아보기

목록 보기
3/4

이 글은 https://bbiguduk.gitbook.io/swift 에 나오는 스위프트 문법을 공부하면서 새롭게 알게 된 지식들을 정리한 포스팅입니다.


배열 (Arrays)

  • 배열은 순서대로 같은 타입의 값을 저장한다.
  • Swift의 Array 타입은 FoundationNSArray 클래스와 연결(Bridge)되어 있다.

빈 배열 생성 (Creating an Empty Array)

  • 컨텍스트 상에서 타입에 대한 정보가 제공되는 경우 []로 해당 타입의 빈 배열로 만들 수 있다.
someInts.append(3)
someInts = []

기본값 배열 생성 (Creating and Array with a Default Value)

  • Array 타입은 크기를 고정하여 기본 값을 할당하여 배열을 생성하는 초기화 함수를 포함한다.
    • String 타입도 가능하다.
var fiveZero = Array(repeating: 0, count: 5) // [Int] [0, 0, 0, 0, 0]
var fiveZeroString = String(repeating: "0", count: 5) // "00000"

배열을 더해 생성 (Creating Array by Adding Two Arrays Together)

  • 같은 타입의 배열을 덧셈 연산자로 합칠 수 있다.
var threeNine = Array(repeating: 9, count: 3)
var eightNumber = fiveZero + threeNine // [0, 0, 0, 0, 0, 9, 9, 9]

배열 접근과 수정 (Accessing and Modifying an Array)

  • 하나 이상의 같은 타입의 요소로 이루어진 배열을 +=로 추가할 수 있다.
var shoppingList = ["Egg", "Flower"]
shoppingList += ["Cheese", "Butter", "Baking Powder"]
  • 서브 스크립트 문법을 사용하여 값을 변경할 수 있다. (인덱스 범위 초과하면 런타임 에러 발생)
    • 범위 연산자를 통해서도 가능한데, 해당 범위의 값들을 지우고 대입하려는 값들을 삽입한다.
    • 이때 범위와 대입하려는 값들의 갯수가 달라도 상관없다.
shoppingList[0] = "Beaf"
shoppingList[1...3] = ["Apple", "Banana", "Candy", "Diamond"]
// ["Beaf", "Apple", "Banana", "Candy", "Diamond", "Baking Powder"]
  • insert(_:at:) : 배열의 특정 인덱스에 요소를 추가할 때 사용한다.
    • at: 에 입력한 인덱스에 위치한 요소의 앞쪽에(=해당 인덱스에) 요소를 삽입한다.
  • remove(at:) : insert와 비슷하게 동작하며, 차이는 삭제한 요소를 반환한다. (필요 없으면 무시)
    • 요소를 삭제하면 배열의 공간도 삭제되어 그 다음 인덱스가 당겨진다.
    • 마지막 아이템을 삭제할 때 count - 1 등을 피하기 위해서 removeLast()를 사용하는 것이 낫다.
shoppingList.insert("Strawberry Jam", at: 0)

var removedItem = shoppingList.remove(at: 0) // Strawberry Jam
print(shoppingList[0]) // Beef

var lastRemovedItem = shoppingList.removeLast() // Baking Powder

배열 반복 (Iterating Over an Array)

  • enumerated() : 각 요소의 인덱스(Int: 0부터 1씩 증가)와 값을 튜플로 조합하여 반환한다.
for (index, value) in shoppingList.enumerated() {
    print("Item \(index + 1) - \(value)")
}

집합 (Sets)

  • 집합은 순서와 상관없이 같은 타입의 값을 저장한다.
  • 요소의 순서가 중요하지 않거나 중복되면 안 될 때 집합을 사용한다.
  • Swift의 Set 타입은 FondationNSSet 클래스와 연결(Bridge)되어 있다.

집합 타입을 위한 해쉬 값 (Hash Values for Set Types)

  • Set에 저장하기 위해 요소의 타입은 hashable(= 해쉬 값 계산 가능)해야 한다.
    • 해쉬 값(hash value)란, 각 객체의 고유한 Int 값으로 해쉬 값이 동일하다면 동일한 객체이다.
    • 모든 기본 타입(String, Int, Double, Bool)은 hashable → 집합과 딕셔너리 키로 사용가능.
    • 연관값 없는 enumcase 값도 hashable하며, 사용자 타입도 Hashable 프로토콜 준수하면 가능.
a == b && a.hashValue == b.hashValue // true

집합 타입 구문 (Set Type Syntax)

  • 초기화 구문으로 타입이 결정된 빈 집합을 생성한다.
    • 리터럴로 초기화 할 경우, 포함된 값의 타입으로 추론할 수 있기 때문에 타입을 명시하지 않아도 된다.
var letters = Set<Character>()
var letters: Set<Character> = [] // 이것도 같다.

var genres: Set = ["Rock", "Classical", "Jazz"]

집합의 접근과 수정 (Accessing and Modifying a Set)

  • count, isEmpty 프로퍼티를 사용할 수 있다.
  • insert(_:), remove(_:), removeAll(), contain(_:) 메서드를 사용할 수 있다.
    • remove(_:)로 반환된 값이 nil일 수도 있기 때문에 Optional 타입 반환한다.

집합 반복 (Iterating Over a Set)

  • Set 타입은 순서가 없지만, sorted() 메서드로 해당 타입 Array로 변환하여 정렬 가능하다.
    • by: > 인자를 사용하여 오름차순 정렬도 가능하다.
for genre in genres.sorted(by: >) {
		print(genre)
}

type(of: genres.sorted()) // Array<String>

기본 집합 연산 (Fundamental Set Operation)

  • intersaction(_:) : 두 집합의 공통값을 가진 Set을 생성한다. → 교집합
  • symmetricDifference(_:) : 두 집합의 공통값을 제외한 값들을 가진 Set을 생성한다. → 대칭 차집합
  • union(_:) : 두 집합의 모든 값을 가진 Set을 생성한다. → 합집합
  • subtracting(_:) : 인자로 전달한 집합과의 공통값을 제외한 값들을 가진 Set을 생성한다. → 차집합
let oddDigits: Set<Int> = [1, 3, 5, 7, 9]
let evenDigits: Set<Int> = [2, 4, 6, 8]
let PrimeNumber: Set = [2, 3, 5, 7]

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

집합 멤버쉽과 동등성 (Set Membership and Equality)

  • 두 집합이 같은 값을 가지고 있는지 판별할 때는 == 연산자를 사용한다.
  • isSubset(of:) : 모든 값이 인자로 전달한 집합에 포함되어 있는지. → 부분집합
  • isStrictSubset(of:) : 인자로 전달한 집합과 같지 않으면서 부분집합인지. → 진부분집합
  • isSuperset(of:) : 인자로 전달한 집합의 모든 값을 포함하고 있는지. → 초집합
  • isDisjoint(of:) : 두 집합 사이에 공통된 값이 있는지. → 분리집합
let houseAnimals: Set<String> = ["Cat", "Dog"]
let farmAnimals: Set<String> = ["Hen", "Horse", "Dog", "Pig", "Cat"]
let cityAnimals: Set<String> = ["Mouse", "Crow"]

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

딕셔너리 (Dictionary)

  • 딕셔너리는 순서와 상관없이 같은 타입의 key와 같은 타입의 value를 저장한다.
    • 값에 대한 식별자로서 각 key는 유니크한 값을 가지며, Hashable 프로토콜을 준수해야 한다.
  • Swift의 Dictionary 타입은 Foundation의 NSDictionary 클래스와 연결(Bridge)되어 있다.
  • Dictionary<Key, Value> 형식으로 작성하며, [Key: Value] 와 같이 축약문법도 가능하다.

빈 딕셔너리 생성 (Creating an Empty Dictionary)

  • 배열과 같이 초기화 구문으로 특정 타입의 빈 딕셔너리를 생성할 수 있다.
    • 리터럴로 초기화 할 경우, 포함된 값의 타입으로 추론할 수 있기 때문에 타입을 명시하지 않아도 된다.
let animals = [Character: String]()
let animals: [Character: String] = [:] // 이것도 같다.

var animals = ["🐶": "Dog", "🐱": "Cat", "🐦": "Bird", "🦁": "Lion"]
// 타입 추론 할 경우 Character가 아닌 String이 된다.

딕셔너리 접근과 수정 (Accessing and Modifying a Dictionary)

  • count, isEmpty 프로퍼티를 사용할 수 있다.
  • 배열과 같이 서브 스크립트 구문을 사용하여 새로운 요소를 추가/변경할 수 있다.
animals["🐤"] = "Bird_MK2"
animals["🐤"] = "Little Bird"
  • updateValue(_:forKey:) 메서드를 사용하여 새로운 요소를 추가/변경할 수도 있다.
    • 서브 스크립트 구문과의 차이는 업데이트 이전 값을 반환한다는 점이다.
    • 해당 키에 값이 존재하지 않을 수도 있으므로 해당 값 타입의 옵셔널을 반환한다.
    • 즉 요소를 추가하는 경우에는 nil을, 요소를 변경하는 경우에는 Optional(ex:String?) 반환한다.
//animals["🐠"] = "???"
print(animals.updateValue("Egg", forKey: "🐠")) // nil -> 위 주석 해제하면 Optional("???")

if let oldValue = animals.updateValue("Fish", forKey: "🐠") {
    print(oldValue) // Egg
} else {
    print("There was no value for 🐠") // 새로 요소를 추가했을 경우 출력
}
  • 서브 스크립트를 사용하여 값을 가져올 수도 있는데, 위와 마찬가지 이유로 Optional 반환한다.
if let animal = animals["🐟"] {
    print(animal)
} else {
    print("There is no value for 🐟")
}
  • removeValue(forKey:) 메서드를 사용하여 키-값 쌍을 삭제할 수 있다.
    • 이때 역시 해당 키에 값이 존재할 경우에는 삭제된 값의 Optional을, 없을 경우에는 nil을 반환한다.
  • 서브 스크립트로 nil을 할당하여 삭제할 수도 있다.
animals["🐠"] = nil

if let removedAnimal = animals.removeValue(forKey: "🐠") {
    print(removedAnimal)
} else {
    print("There is no 🐠")
}

딕셔너리 반복 (Iterating Over a Dictionary)

  • for-in 루프에서 각 아이템의 키-값 쌍을 (key, value) 튜플로 반환받을 수 있다.
for (animal, name) in animals {
    print("\(animal) = \(name)", terminator: " ")
}
// 🐱 = Cat 🐶 = Dog 🦁 = Lion 🐤 = Little Bird 🐦 = Bird
  • keysvalues 프로퍼티로 각 키와 값에 대한 Collection을 반환받을 수 있다.
    • Array처럼 보이지만, KeysValues라는 별개의 Collection이다.
    • 배열의 API 사용해야할 경우 Array로 캐스팅하여 사용할 수 있다.
type(of: animals.keys) // Keys
type(of: Array(animals.values)) // Array<Stirng>

let animalNames = [String](animals.values) 
// ["Little Bird", "Dog", "Cat", "Bird", "Lion"]
profile
var yona = IOSDeveloper(stage: 0)

0개의 댓글