티스토리 뷰

iOS/Swift

Swift, Set 톺아보기

iOS 개발자, 였던 것 2023. 4. 18. 23:33

최근에 알고리즘 공부 이야기를 하다가, Set에 대한 이야기가 나왔다.

중복 제거에 흔히 사용하는 Set은 어떻게 동작하는지, 또 Swift의 Set은 뭐가 다른지를 간단하게 적어보려 한다.


Set?

A set stores distinct values of the same type in a collection with no defined ordering. You can use a set instead of an array when the order of items isn’t important, or when you need to ensure that an item only appears once.

기본적으로 Set은 중복되지 않는 값을 저장하기 위한 Collection으로 정렬되지 않은 상태로 들어간다. 들어오는 데이터의 정렬 순서가 중요하지 않거나, 단 한 번만 보여주고 싶은 경우에 사용하라고 되어있다. 여기까지는 일반적으로 알고 있는 Set에 대한 설명과 사용 사례다.

 

A type must be hashable in order to be stored in a set — that is, the type must provide a way to compute a hash value for itself. A hash value is an Int value that’s the same for all objects that compare equally, such that if a == b, the hash value of a is equal to the hash value of b. All of Swift’s basic types (such as String, Int, Double, and Bool) are hashable by default, and can be used as set value types or dictionary key types. Enumeration case values without associated values (as described in Enumerations) are also hashable by default.

이 부분이 중요하지 않을까 싶은데 Hashable한 객체만 저장이 가능하다. 기본적으로 String, Int, Double, Bool 등이 Hashable을 지원하고 있다고 한다. 간단하게 Swift내 기본 자료형들은 지원한다고 생각하면 될 듯

직접 만든 클래스나 구조체의 경우에도 Hashable 프로토콜을 지원하게 끔 확장한다면 Set으로 관리할 수 있는데, 이는 Set에 값을 추가하는 경우에 hash 값으로 변환하여 값이 있는지 확인 후에 들어가기 때문에 그러하다.

 

참고로 클래스나 구조체 안에 다른 클래스나 구조체가 들어있는 경우 해당 클래스, 구조체도 Hashable이어야 Set을 사용할 수 있다.

 

Set에 대한 정보를 찾아보다가 재미있는 것을 발견했는데, 사실 이 글을 적기 직전까지도 이런 함수를 제공해주고 있었는지는 몰랐다.

Set은 기본적으로 집합을 의미하는 만큼 집합과 관련된 연산을 Swift에서 지원하고 있다.

 

intersection, symmetricDifference, union, subtracting, subSet, superSet, disjoint와 같은 연산자들이 그 예이다. 

let firstSet: Set = [1,2,3,4,5,6]
let secondSet: Set = [5,6,7,8]

print(firstSet.union(secondSet).sorted())
// 합집합, [1, 2, 3, 4, 5, 6, 7, 8]

print(firstSet.subtracting(secondSet).sorted())
// 차집합, [1, 2, 3, 4]

print(firstSet.intersection(secondSet).sorted())
// 교집합, [5, 6]

print(firstSet.symmetricDifference(secondSet).sorted())
// XOR 집합(합집합 - 교집합), [1, 2, 3, 4, 7, 8]
// 아래와 동일한 결과를 나타냄
// firstSet.union(secondSet).subtracting(firstSet.intersection(secondSet)).sorted()

let subSet: Set = [5,6]
let otherSet: Set = [7,8]
print(otherSet.isSubset(of: secondSet))
print(otherSet.isStrictSubset(of: secondSet))
// otherSet이 완벽하게 secondSet에 포함되므로, true

print(firstSet.isSuperset(of: subSet))
print(firstSet.isStrictSuperset(of: subSet))
// firstSet이 subSet을 완벽하게 포함하므로, true

print(firstSet.isDisjoint(with: otherSet))
// firstSet과 otherSet은 겹치는 부분이 없으므로, true

 

 

처음 글을 작성할 때에는 오늘 중에 Hashable과 Equatable을 같이 다루려고 했으나, 일단 한 번 끊고 가기로 하였다.

집합을 Set이라고 배웠었는데, 잊고 살다가 오래간만에 다시 떠올린 기분이었다.

 

부족한 글이지만, 읽어주셔서 감사합니다. 항상 잘못된 내용에 대한 지적은 감사히 받고 있습니다.

 

참고 문서

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/collectiontypes

https://andybargh.com/swift-sets/

'iOS > Swift' 카테고리의 다른 글

Swift에서의 Class와 Struct  (0) 2023.04.27
Swift, Equatable?  (0) 2023.04.21
ViewController와 LifeCycle - 2, LifeCycle  (0) 2023.04.18
ViewController와 LifeCycle - 1, UIViewController  (0) 2023.04.16
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함