5.2.4 집합 연산
기본 집합 연산
집합 자료형은 우리가 수학에서 배웠던 집합의 개념과 거의 동일합니다. 이 때문에 집합 자료형끼리는 집합 연산이 가능합니다. 스위프트에서는 집합끼리의 연산을 쉽게 처리할 수 있도록 여러 메서드를 제공합니다.
intersection(_:)
수학에서의 교집합입니다. 양쪽 집합에서 공통되는 아이템만 선택하여 새로운 집합을 만들어 주는 메서드입니다
symmetricDifference(_:)
교집합의 여집합입니다. 양쪽 집합에서 공통되는 교집합을 제외하고 한쪽에만 포함된 아이템을 집합으로
만들어주는 메서드입니다
union(_:)
수학에서의 합집합입니다. 양쪽 집합에 있는 아이템을 선택하여 새로운 집합을 만들어 주는 메서드입니다
subtract(_:)
수학에서의 차집합입니다. 한쪽 집합에 있는 모든 아이템에서 다른 쪽 집합에도 속하는 공통 아이템을 제외하고
새로운 집합을 만들어주는 메서드입니다. 주로 한쪽 집합에서 다른 쪽 집합을 빼는 연산으로 처리됩니다
이 중 subtract(_:) 를 제외하면 나머지 메서드는 양쪽 집합의 위치가 바뀌더라도 결과값은 동일합니다. 즉 두 집합 중 하나를 객체로 사용하고 다른 하나를 인자값으로 사용하더라도 결과에는 차이가 없다는 것입니다
var oddDigits: Set = [1,3,5,7,9] // 홀수 집합
let evenDigits: Set = [0,2,4,6,8] // 짝수 집합
let primeDigits: Set = [2,3,5,7] // 소수 집합
1. oddDigits.intersection(evenDigits).sorted()
// []
2. oddDigits.symmetricDifference(primeDigits).sorted()
// [1,2,9]
3. oddDigits.union(evenDigits).sorted()
// [0,1,2,3,4,5,6,7,8,9]
4. oddDigits.subtract(primeDigits)
oddDigits.sorted()
// [1,9]
1번에서 intersection(_:)은 교집합으로 홀수 집합과 짝수 집합간 공통된 아이템이 없으므로 빈 집합 즉 공집합입니다
2번에서 symmetricDifference(_:)는 교집합을 제외한 집합이므로 아이템 3,5,7이 제외되고 나머지 아이템을 반환합니다
3번에서 union(_:)은 합집합입니다. 홀수 집합과 짝수 집합 간에 교집합이 없으므로 두 집합의 아이템을 합쳐서 반환합니다'
4번에서 subtract(_:)은 차집합입니다. 두 집합 사이의 교집합은 3,5,7이므로 결과값은 [1,9]가 됩니다. 하지만 또 알아야 할 점이 있습니다. subtract(_:)는 위 3개의 함수와 달리 대상 집합의 내용을 직접 변경합니다. 위의 3개 함수는 연산이 완료되고 난 새로운 집합을 반환하고 원래의 집합을 변경하지 않습니다. 하지만 subtract(_:)은 대상 집합을 직접 변경하여 oddDigits에는 원래의 집합이 아니라 [1,9]가 저장되어 있는 것입니다. 이렇게 변경 가능성이 있기 때문에 oddDigits는 상수 let이 아닌 변수 var로 선언되어야 합니다. 또한 subtract(_:)는 값을 반환하지 않기 때문에 뒤이어 바로 sorted()를 사용할 수 없습니다.
부분집합과 포함관계 판단 연산
우리가 중고등학교 시절 배운 바에 따르면 집합 A의 모든 원소가 집합 B에도 있는 경우 집합 A는 집합 B의 부분집합이 됩니다. 프로그래밍의 관점으로 이야기하면 집합 A와 B의 아이템이 모두 일치할 때 A==B가 성립하며 이와 동시에 두 집합은 서로의 부분집합이 됩니다. 스위프트에서는 집합 자료형에 대해 부분집합 관계를 확인해주는 메서드를 제공합니다
isSubset(of:)
주어진 집합의 값 전체가 특정 집합에 포함되는지를 판단하여 true, false를 반환합니다. 수학적으로 이야기하면
하나의 집합이 다른 집합의 부분집합인지 여부를 판단합니다
isSuperset(of:)
주어진 집합이 특정 집합의 모든 값을 포함하는지를 판단하여 true, false를 반환합니다. isSubset(of:)와는
반대 상황을 판단하는 것으로, 집합이 다른 집합이 상위집합 역할을 하는가에 대한 판단을 담당하는 메서드라고
할 수 있습니다
isStrictSubset(of:)와 isStrictSuperset(of:)
조금 전 설명한 두 메서드처럼 주어진 집합이 특정 집합의 부분집합인지 아니면 상위집합인지를 판단하는 역할을 하지만
두 집합이 서로 같은 경우의 결과값이 다르게 반환됩니다. 두 집합이 서로 일치할 경우 수학적으로는 서로가 서로의
부분집합이자 상위집합이 될 수 있으므로 isSubset(of:), isSuperset(of:) 메서드가 true를 반환하는 반면,
isStrictSubset(of:)와 isStrictSuperset(of:) 메서드는 이를 더 엄격하게 판단하여 정확히는 부분집합
또는 상위집합일 때만 true를 반환합니다. 서로 일치하지 않는 집합은 동일한 집합으로 판단하고, 부분집합이나
상위집합으로 판단하지 않는다는 뜻입니다
isDisjoint(with:)
두 집합 사이의 공통 값을 확인하여 아무런 공통 값이 없을때 true, 공통 값이 하나라도 있으면 false를 반환합니다
예제로 확인해 보겠습니다
let A: Set = [1,3,5,7,9]
let B: Set = [3,5]
let C: Set = [3,5]
let D: Set = [2,4,6]
1. B.isSubset(of: A) // true
2. A.isSuperset(of: B) // true
3. C.isStrictSubset(of: A) // true
4. C.isStrictSubset(of: B) // false
5. A.isDisjoint(with: D) // true
집합 B의 아이템은 집합 A에 모두 속해있으므로 true를 반환합니다
집합 B가 A의 부분집합이라는 것은 A가 B의 상위집합이라는 것으로 true를 반환합니다
A는 C의 부분집합이므로 true를 반환합니다
B와 C는 동일한 집합으로 isStrictSubset(of: B)의 실행 결과는 false 입니다
A와 D는 교집합이 공집합이므로 true를 반환합니다
다음으로는 배열에서 중복 아이템을 제거하는 방법을 알아보겠습니다
var A = [4,2,5,1,7,4,9,11,3,5,4] // 배열
let B = Set(A) // 집합
A = Array(B) // 중복이 제거된 배열
// [2,4,9,5,7,3,1,11]
위 과정은 배열 객체를 집합 객체로 만들었다가 다시 배열 객체로 만들어주고 있습니다. 집합으로 만들면서 중복이 제거되고 그것을 다시 배열로 만드는 것입니다. 하지만 이 과정을 짧게 줄일 수 있습니다
A = Array(Set(A))
Last updated