본문 바로가기

Swift/기초 문법

컬렉션 타입 2편 - 집합

https://bbiguduk.gitbook.io/swift/language-guide-1/collection-types#accessing-and-modifying-an-array

 

콜렉션 타입 (Collection Types) | Swift

배열, 집합, 그리고 딕셔너리를 사용하여 데이터를 구성합니다. Swift는 콜렉션의 값을 저장하기 위한 배열 (array), 집합 (set), 딕셔너리 (dictionary)와 같은 3개의 원시적인 콜렉션 타입 (collection types)

bbiguduk.gitbook.io

 

  • 집합 (set) 은 콜렉션에 순서와 상관없이 같은 타입의 다른 값을 저장합니다.
let numbers = [1, 2, 3, 3, 2, 1]
let uniqueNumbers = Set(numbers) // {1, 2, 3}
let sortedUniqueNumbers = Array(uniqueNumbers).sorted() // [1, 2, 3]
struct Student: Hashable {
    let id: Int
    let name: String
}

let students: Set = [
    Student(id: 1, name: "Alice"),
    Student(id: 2, name: "Bob"),
    Student(id: 1, name: "Alice") // 중복으로 간주됨
]

print(students.count) // 2
  • 아이템의 순서가 중요하지 않거나 아이템이 반복되면 안될 때 배열 대신에 집합을 사용할 수 있습니다.

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

  • 집합 (set) 에 저장하기 위해 타입은 반드시 hashable 여야 합니다.
  • 즉, 해쉬 값 (hash value) 을 계산할 수 있는 방법을 타입은 제공해야 합니다.
  • 해쉬 값은 동일하게 비교되는 모든 객체에 대해 동일한 Int 값으로 a == b 이면 a.hashValue == b.hashValue 를 따릅니다.

 

집합 타입 구문 (Set Type Syntax)

  • Swift 집합의 타입은 Element 가 집합의 저장할 값의 타입을 나타내는 Set<Element> 로 작성됩니다.
  • 배열과 반대로 집합은 짧은 등가 형식이 없습니다.

 

빈 집합 생성과 초기화 (Creating 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.insert("a")
// letters now contains 1 value of type Character
letters = []
// letters is now an empty set, but is still of type Set<Character>

 

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

  • 집합 콜렉션으로 하나 이상의 값으로 짧은 방법과 같이 배열 리터럴을 사용하여 집합을 초기화 할 수도 있습니다.
  • 아래 예제는 String 값을 저장하는 favoriteGenres 라는 집합을 생성합니다:
var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]
// favoriteGenres has been initialized with three initial items
  • favoriteGenres 변수는 Set<String> 라고 쓰고 "String 값의 집합" 으로 선언됩니다.
  • 이 집합은 특정 String 타입의 값을 가지고 있기 때문에 String 값만 저장할 수 있습니다.
  • 여기서 favoriteGenres 집합은 배열 리터럴 안에 적힌 3개의 String 값 ("Rock", "Classical", "Hip hop")으로 초기화 됩니다.
  • 집합 타입은 배열 리터럴에서 추론할 수 없기 때문에 Set 타입은 명시적으로 선언해야 합니다.
  • 그러나 Swift의 타입 추론 때문에 배열 리터럴로 초기화 할 때 하나의 타입의 값이 포함되어 있는 경우 집합 요소의 타입을 명시하지 않아도 됩니다. favoriteGenres 초기화는 짧게 쓸 수 있습니다:
var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"]
  • 배열 리터럴 안에 값은 같은 타입이기 때문에 Swift는 favoriteGenres 변수를 사용하는데 Set<String> 이라고 유추할 수 있습니다.

 

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

  • 메서드와 프로퍼티로 집합에 접근과 수정할 수 있습니다.
  • 읽기 전용 count 프로퍼티로 집합의 아이템 갯수를 알 수 있습니다:
print("I have \\(favoriteGenres.count) favorite music genres.")
// Prints "I have 3 favorite music genres."
  • count 프로퍼티가 0 과 같은지를 부울 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."
  • 집합의 insert(_:) 메서드를 호출하여 집합에 새로운 아이템을 추가할 수 있습니다:
favoriteGenres.insert("Jazz")
// favoriteGenres now contains 4 items
  • 집합의 remove(_:) 메서드를 호출하여 집합의 아이템을 삭제할 수 있습니다.
  • remove(_:) 메서드는 집합에 아이템이 있을 경우 삭제하고 삭제된 값을 반환하거나 해당 아이템이 없을 경우 nil 을 반환합니다.
  • 또한 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."
  • contain(_:) 메서드를 사용하여 집합에 특정 아이템이 포함되어 있는지 알 수 있습니다.
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의 Set 타입은 정의된 순서를 가지고 있지 않습니다.
  • 특정 순서로 집합의 값을 반복하려면 집합의 요소를 < 연산자를 사용하여 정렬하여 반환하는 sorted() 메서드를 사용합니다.
for genre in favoriteGenres.sorted() {
    print("\\(genre)")
}
// Classical
// Hip hop
// Jazz

 

집합 연산 수행 (Performing Set Operations)

두 집합을 합치거나 두 집합의 공통 값을 구하거나 두 집합이 모두 같은 값을 갖고 있거나 한쪽에만 존재하거나 아예 없거나와 같은 기본적인 집합 연산을 효율적으로 수행할 수 있습니다.

 

기본 집합 연산 (Fundamental Set Operations)

  • intersection(_:) 메서드를 사용하면 두 집합의 공통 값을 가지는 새로운 집합을 생성합니다.
  • symmetricDifference(_:) 메서드를 사용하면 두 집합의 공통 값을 제외한 새로운 집합을 생성합니다.
  • union(_:) 메서드를 사용하면 두 집합의 모든 값으로 새로운 집합을 생성합니다.
  • subtracting(_:) 메서드를 사용하면 특정 집합의 공통 값을 제외한 새로운 집합을 생성합니다.
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)

  • isSubset(of:) 메서드를 사용하면 집합이 특정 집합에 모든 값이 포함되어 있는지 판단합니다.
  • isSuperset(of:) 메서드를 사용하면 집합에 특정 집합에 모든 값을 포함 하는지 판단합니다.
  • isStrictSubset(of:) 또는 isStrictSuperset(of:) 메서드를 사용하면 집합이 특정 집합과 같지 않고 부분집합인지 초집합인지 판단합니다.
  • isDisjoint(with:) 메서드를 사용하면 두 집합이 공통 값이 없는지 판단합니다.
let houseAnimals: Set = ["🐶", "🐱"]
let farmAnimals: Set = ["🐮", "🐔", "🐑", "🐶", "🐱"]
let cityAnimals: Set = ["🐦", "🐭"]

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

 

 

불변 Set과 가변 Set

  • let으로 선언된 집합은 불변이며, 수정이 불가능합니다.
  • var로 선언된 집합은 가변이며, 수정할 수 있습니다. 
let constantSet: Set<String> = ["A", "B", "C"]
// constantSet.insert("D") // Error: Cannot use mutating method on immutable value

var mutableSet: Set<String> = ["A", "B", "C"]
mutableSet.insert("D") // Success

 

Custom Set Items

  • Set에 사용자 정의 타입을 저장하려면 그 타입이 Hashable 프로토콜을 준수해야 합니다.
  • Hashable은 Swift 기본 제공 프로토콜로, Equatable을 상속하며 해시 값을 제공하기 위해 hash(into:) 메서드를 구현해야 합니다. 
struct Person: Hashable {
    let name: String
    let age: Int
}

let people: Set = [
    Person(name: "Alice", age: 30),
    Person(name: "Bob", age: 25)
]

 

Set과 기타 컬렉션 변환

  • Set은 다른 컬렉션과 쉽게 변환 가능합니다:
    • 배열로 변환: Array(set)
    • 집합으로 변환: Set(array) 
let array = ["a", "b", "c", "a"]
let set = Set(array) // {"a", "b", "c"} 중복 제거
let backToArray = Array(set).sorted() // ["a", "b", "c"]

 

'Swift > 기초 문법' 카테고리의 다른 글

컬렉션 타입 3편 - 딕셔너리  (0) 2024.12.11
컬렉션 타입 1편 - 배열  (0) 2024.12.10
enum 케이스 나누기  (0) 2024.12.02
기본 연산자 (Basic Operators)  (0) 2024.12.02