728x90
세트 선언
- 세트는 서로 중복되지 않고 unique, nil이 포함되지 않ㅇ느 non-nil 순위를 정의할 수 없는 무순위 컬렉션이다
- 세트는 형식상 Hashable 프로토콜에 부합, 스위프트의 모든 기본 타입은 기본적으로 Hashable 프로토콜을 따르도록 설계
- 열거형의 case값 역시 기본적으로 Hashable 프로토콜을 따른다. 세트에는 여러분이 만든 커스텀 타입도 저장할 수 있는데, 이때 Hashable 프로토콜과 Equatable 프로토콜에 부합해야만 함, Hashable은 Equatable을 상속한 프로토콜
- 순위가 중요치 않은 배열이라면 해당 데이터를 세트로 저장해도 큰 차이가 없으며, 이때는 해당 요소가 서로 중복되지 않도록 해야함
- 세트는 배열에 비해 매우 효율적이며, 데이터 접근 속도 역시 세트가 훨씬 빠르다.
- 예시) 배열의 크기가 n일 때 배열 요소에 대한 최악의 검색 시나리오의 효율을 O(n)라고 한다면, 세트의 효율은 크기에 관계 없이 O(1) 수준을 유지한다.
세트 초기화
- 스위프트의 타입추론을 하지 않아 개발자가 직접 Set 타입을 명시적으로 선언
// 세트 선언을 위한 정식 문법
var stringSet = Set<String>()
// 배열 요소로 세트 초기화
var stringSet1: Set = ["Mary", "Bulmang", "PT"]
print(stringSet1.debugDescription)
세트 요소 변경 및 가져오기
- 세트에 새로운 요소를 추가하려면 insert(_:) 메소드를 사용하고, 특정 요소가 이미 세트에 포함돼 있는지 여부를 확인할때는 contains() 메소드를 사용
- 세트안 삭제하려는 요소의 인스턴스를 알고 있을 때 remove()메소드 사용
- 세트의 수가 0보다 큰 경우 removeFirst() 메소드를 이용해서 해당 요소를 삭제
- 세트 내 모든 요소를 삭제하려면 removeAll()
var stringSet2: Set = ["Erik", "Mary", "Michael", "John", "Sally"] // ["Mary", "Michael", "Sally", "John", "Erik"]
stringSet2.insert("'Patrick")
// ["Mary", "Michael", "Sally", "Patrick", "John", "Erik"]
if stringSet2.contains ("Erik") {
print ("Found element")
} else {
print ("Element not found")
}
// 해당 요소 발견
stringSet2.remove("Erik")
// ["Mary", "Sally", "Patrick", "John", "Michael"]
if let idx = stringSet.index(of: "John") {
stringSet.remove(at: idx)
}
// ["Mary", "Sally", "Patrick", "Michael"]
stringSet2.removeFirst()
stringSet2.removeAll()
- 세트 역시 배열이나 딕셔너리와 마찬가지로 for…in 순환문을 이용 가능
- 스위프트의 세트 타입은 무순위, sort 메소드를 이용해서 원하는 순서대로 정렬 가능
for name in stringSet3 {
print("name = \\(name)")
}
for name in stringSet3.sorted() {
print("name = \\(name)")
}
세트 연산자
- 수학에서 집합 개념을 기반으로 만든 타입, 수학의 집합 연산과 같이 두 개 세트의 비교를 위한 다양한 메소드를 제공, 두 개 세트의 멤버십 연산과 동등 연산 기법 역시 제공
세트의 비교 연산
- 세트 타입은 두 개 세트 간의 연산을 위해 합집합, 교집합 연산을 포함
- 네 개의 연산 메소드를 제공, 새로운 세트가 반환되거나 Inplace같은 메소드를 이용하여 기존 세트의 내용을 대체하기도 함
- union, formunion 메소드는 새로운 세트를 만들고, 두 개 세트의 합집합으로 원본 세트를 업데이트
- intersection 메소드와 formIntersection() 메소드는 새로운 세트를 만들고, 두 개 세트의 교집합으로 원본 세트를 업데이트함
- symetricDifference()메소드와 formSymmetricDifference() 메소드는 새로운 세트를 만들고, 두 개 세트의 여집합 요소로 원본 세트를 업데이트
- subtracting(), subtract() 메소드는 새로운 세트를 만들고, 두 개 세트의 차집합 요소로 원본 세트 업데이트
let adminRole: Set = ["READ", "EDIT", "DELETE","CREATE", "SETTINGS" ,"PUBLISH", "LANY", "ADD_USER", "EDIT_USER", "DELETE_USER"]
let editorRole: Set = ["READ", "EDII","DELETE", "CREATE", "PUBLISH_ANY"]
let authorRole: Set = ["READ", "EDIT_OWN","DELETE_OWN", "PUBLISH_ OWN", "CREATE"]
let contributorRole: Set = ["CREATE", "EDIT_OWN"]
let subscriberRole: Set = ["READ" ]
// 두 개 세트에 있는 요소를 모두 포함시킴
let fooResource = subscriberRole.union(contributorRole)
// 두 개 세트에 공통적으로 있는 요소를 포함시킴
let commonPermissions = authorRole.intersection(contributorRole)
// 한쪽에는 있지만, 다른 쪽에는 없는 요소만 포함
let exclusivePermissions = authorRole.symmetricDifference(contributorRole)
부분 집합 및 동등 연산자
- 두 개의 세트에 속한 내부 요소가 완전히 같을 경우, 두 세트는 동등하다고 표현
- == 연산자를 사용하며, 이 연산자를 이용해서 두 개의 세트에 같은 요소들만 포함돼 있는지 확인
// 세트 요소의 순서는 상관없다.
var sourceSet: Set = [1, 2, 3]
var dataSet: Set = [1, 2, 3]
var isequal = sourceSet == dataSet
- inSubset: 어떤 세트의 요소가 특정 세트에 모두 포함되어있는지 확인
- inStrictSubset: 어떤 세트의 요소가 특정세트에 모두 포함되어있지만, 동등 집합은 아님
- inSuperset: 특정 세트의 모든 요소가 또 다른 세트에 모두 포함되어있는지 확인
- inStrictSuperset: 특정 세트의 모든 요소가 또 다른 세트에 모두 포함돼있지만, 동등 집합은 아님
- inDisjoint: 두 세트에 공통 요소가 포함돼 있는지 여부 확인
let contactResource = authorRole
// "EDIT_ONN", "PUBLISH_OWN", "READ","DELETE_OWN", "CREATE"
let userBob = subscriberRole
// "READ"
let userSally = authorRole
// "EDIT_OWN", "PUBLISH_OWN", "READ", "DELETE_OWN", "CREATE"
if userBob.isSuperset(of: fooResource) {
print ("Access granted")
} else {
print ("Access denied")
}
// "Access denied"
if userSally.isSuperset(of: fooResource) {
print ("Access granted")
} else {
print ("'Access denied")
}
// Access granted
authorRole.isDisjoint(with: editorRole)
editorRole.isSubset(of: adminRole)
튜플의 특징
- 튜플은 배열, 딕셔너리, 세트와 같은 컬렉션 타입은 아니지만, 컬렉션과 매우 비슷한 특징
- 튜플에는 하나 이상의 데이터 타입을 함께 담을 수 있으며, 배열 등 다른 컬렉션 타입과 달리, 내부 요소들이 모두 같은 타입 필요 없다.
- 다양한 데이터를 담을 수 있다
- 컬렉션이 아니기 때문에, SequecneType 프로토콜을 따르지 않으며, 내부 요소 순회 불가능
- 한 무리의 데이터를 저장하거나 전달하기 위한 목적으로 사용
- 구조체 타입을 쓰지 않고 함수에서 하나의 값으로 여러 타입의 데이터를 반환해야 하는 경우 유용
- 튜플은 임시그룹에 만드는데 유용, 복잡한 데이터 구조를 만드는데 적합하지 않음, 임시 범위를 넘어 영구 범위이면 튜플 대신 클래스 또는 구조체로 만드는 것이 남
무기명 튜플
- 튜플은 숫자, 데이터 타입을 조합해서 만들 수 있음
기명 튜플
- 개별 요소에 이름을 붙일 수 있는 튜플
- 코드를 이해하기 쉽게 해주며, 메소드를 통해 튜플을 반환할 때 특정 인덱스 위치에 어떤 값이 있는지 알기 쉽게 도와줌
let response1 = (errorCode: 4010, errorMessage:"Invalid file contents", offset: 0x7fffffffffffff)
- 튜플은 메소드를 통해 구조화된 값을 임시로 전달할 때 특히 유용한 타입
- 메소드에 의해 튜플을 반환할 때는 클래스를 정의할 때 필요한 정보 혹은 여러 타입의 값을 지니고 있는 딕셔너리를 이용할 때 필요한 정보와 같은 것을 추가적으로 전달할 수 있음
func getPartnerList() -> (statusCode: Int, description:String, metaData:(partnerStatusCode: Int, partnerErrorMessage: String, parterTraceId:String)) {
// 에러발생
return (503, "Service Unavailable", (3223, "system is down for maintainace until 2022~!~!~!", "5ABSDFSDFC0-SDFSDFSDF-ASDASHGH1"))
}
var result = getPartnerList()
result.statusCode
result.description
result.metaData.partnerErrorMessage
result.metaData.partnerStatusCode
result.metaData.parterTraceId
728x90
'SwiftUI > 정리' 카테고리의 다른 글
[SwiftUI] TCA(The Composable Architecture)이란? (0) | 2024.03.18 |
---|---|
[SwiftDataStructure&Algorithms] 기본 데이터 구조(배열, 딕셔너리) (0) | 2024.03.13 |
[SwiftDataStructure&Algorithms] 데이터 구조 (1) | 2024.03.12 |
XCODE IOS 프로파일링 디버깅 하는 방법 (1) | 2024.01.07 |
[SwiftUI] 아키텍처 고민 (0) | 2024.01.06 |