집합은 같은 타입의 데이터 값을 특정한 순서 없이 저장한다. 이때 중복된 데이터는 허용되지 않는다.
a==b
하다면 a
와 b
객체의 해쉬 값은 같다. 즉 해쉬 값을 통해 인스턴스가 같은지 여부를 확인할 수 있다. 이때 집합에 특정한 값이 저장되려면, 이 타입 자체에 대한 해쉬 값 계산 방법이 있어야 한다.
스위프트가 지원하는 기본적인 타입(문자열, 정수, 더블, 불리언 타입 등)은 모두 해쉬 가능하므로 집합과 딕셔너리에 사용할 수 있다.
사용자가 직접 hash(into:)
메소드를 통해 해쉬 가능한 커스텀 타입을 선언할 수 있다.
집합을 선언하는 정식 문법은 Set<Element>
이다. 배열과 달리 단축어가 존재하지 않는다.
var set_char = Set<Character>()
를 통해 캐릭터 타입의 값을 저장 가능한 빈 집합 객체를 선언할 수 있다.
배열과 마찬가지로 이미 함수 파라미터로 추론 가능한 타입 정보를 전달했다면 Set<Character>()
없이 []
만으로도 빈 집합을 선언할 수 있다.
set_char.insert("a")
set_char = []
// set_char: []
이때 a
라는 캐릭터를 이 집합 set_char
에 삽입했다는 정보가 있다. 따라서 []
로 값을 모두 비우라는 코드에 특정 타입이 없더라도 자동으로 추론할 수 있다.
배열 리터럴을 통해서도 집합을 만들 수 있다.
var set_genres: Set<String> = ["pop", "rock", "hip-hop"]
리터럴로 선언한 배열 내 값이 set_genres
라는 문자열 집합 내부에 들어간다. 이때 배열 안에 들어 있는 값이 모두 문자열이기 때문에 스위프트는 타입 추론을 통해 Set
만으로도 선언 가능하다.
var set_genres: Set = ["pop", "rock", "hip-hop"]
// same as Set<String> in this case
집합 메소드와 프로퍼티를 통해 값에 접근하거나 수정하자.
Set.isEmpty
프로퍼티는 집합이 비었는지 확인한다. 비었다면 True
, 값이 있다면 False
를 return.
Set.insert(_:)
메소드를 통해 집합에 아이템을 삽입한다.
Set.remove(_:)
메소드를 통해 집합에 아이템을 삭제한다. 파라미터를 통해 전달한 아이템이 집합에 있으면 집합 삭제 및 반환, 없다면 널 값만 반환한다.
모든 아이템을 삭제하고 싶다면 Set.removeAll()
메소드가 있다.
배열처럼 집합 또한 for-in
루프문으로 사용할 수 있다. 이때 접근하는 순서를 조정하려면 sorted()
메소드를 사용하자.
for genre in set_genres.sorted() {
print("\(genre)")
}
// hip-hop
// pop
// rock
교집합 : Set.intersection(_:)
을 사용해 교집합을 반환한다.
대칭차집합 : Set.symmetricDifference(_:)
을 사용해 합집합에서 교집합을 뺀 나머지 부분을 반환한다.
합집합 : Set.union(_:)
을 사용해 합집합을 반환한다.
차집합 : Set.subtracting(_:)
을 사용해 a
에서 교집합을 뺀 부분을 반환한다.
let odds: Set = [1, 3, 5, 7, 9]
let evens: Set = [0, 2, 4, 6, 8]
let primes: Set = [2, 3, 5, 7]
odds.union(evens).sorted()
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
odds.intersection(evens).sorted()
// []
odds.subtracting(primes).sorted()
// [1, 9]
odds.symmetricDifference(primes).sorted()
// [1, 2, 9]
==
연산자로 두 집합이 가진 값이 모두 같은지 확인한다.
a.isSubset(of:b)
메소드로 a
가 b
의 부분 집합인지 확인한다.
a.isSuperset(of:b)
메소드로 a
가 b
를 포함하는 집합인지, 즉 b
가 a
의 부분 집합인지 확인한다.
a.isStrictSubset(of:b)
, a.isStrictSuperset(of:b)
메소드로 a
가 b
의 부분 집합 또는 포함 집합인지 확인할 수 있다. 이때 중요한 건 a
와 b
가 완전히 동일한 집합이 아닐 때 strict하다는 점이다.
a.isDisjoint(with:)
메소드로 a
와 b
가 서로소 집합인지 확인한다.
let set_1: Set = [1, 2, 3]
let set_2: Set = [2, 3]
let set_3: Set = [4, 5, 6]
set_1.isSuperset(of: set_2)
// true
set_2.isDisjoint(with: set_3)
// true