Set은 해시 테이블로 구현된 고유한 요소의 비순서 컬렉션입니다. Array와의 주요 차이점은 중복 값이 없고 순서가 없다는 것입니다. 주요 인터페이스: 삽입 방법(insert), 삭제 방법(remove), 존재 여부 확인 방법(contains).
연산 시간:
insert, remove 및 contains 작업은 평균적으로 O(1)로 작동합니다.사용 예:
var numbers: Set<Int> = [1, 2, 3] numbers.insert(4) // Set: 1, 2, 3, 4 numbers.insert(2) // Set는 변경되지 않음, 2는 이미 존재 numbers.remove(1) // Set: 2, 3, 4 print(numbers.contains(3)) // true
순서가 중요하지 않지만 고유성이 중요한 경우 Set을 사용하세요. Array와 비교:
Array에서 요소 삭제 및 검색은 O(n)로 수행됩니다.Array는 중복 값을 허용합니다.Set은 ∪, ∩, −, ⊆, ⊇ 및 기타 집합 이론 연산을 지원합니다.
질문:
다음 코드가 컴파일될까요? 그 이유는 무엇인가요?
let set: Set = [[1, 2], [3, 4]]
답변:
아니요, 컴파일되지 않습니다. Set은 요소의 유형이 Hashable 프로토콜을 준수해야 합니다. 배열(Array)은 Hashable을 구현하지 않기 때문에 배열의 집합을 직접 만들 수 없습니다. 예를 들어, Set<Int>는 올바르지만 Set<[Int]>는 올바르지 않습니다.
이야기
한 서비스에서 개발자들은 고유 객체 식별자를 [Int]로 저장했으며 Set<Int>로 저장하지 않았습니다. 이로 인해 문제가 발생했습니다: 존재 여부 체크 및 삭제가 느리게 작동했으며(시간 — O(n)), 중복이 발생하고 비즈니스 로직이 깨졌습니다.
이야기
비표준 유형을 Set에 넣으려는 시도(예: Set<MyModel> 생성)도 이루어졌지만, 해당 유형은 Hashable을 구현하지 않았습니다. 관련 프로토콜을 추가한 후에 코드가 컴파일되었지만, hash(into:) 구현에 오류가 발생하면 충돌이 발생하고 실행 중 예측할 수 없는 동작이 발생했습니다.
이야기
개발자는 Set의 요소 반복 순서가 삽입 순서와 같을 것이라고 기대하며 UI를 동일한 순서로 구성했습니다. 결과적으로 매번 실행할 때 순서가 달라지고, 이는 최종 사용자에게 데이터가 일관되지 않게 표시되는 원인이 되었습니다.