typealias MyInt = Int
typealias YourInt = Int
// MyInt, YourInt 둘다 같은 Int를 표현하는 방법
var person: (String, Int, Double) = ("Jin", 28, 179)
print("이름: \(person.0), 나이: \(person.1), 신장:\(person.2)")
var person: (name: String, age: Int, height: Double) = ("Jin", 28, 179)
typealias PersonTuple = (name: String, age: Int, height: Double)
let Jin: PersonTuple = ("Jin", 28, 179)
let Eric: PersonTuple = ("Eric", 20, 173)
print("이름: \(Jin.name), 나이: \(Jin.age), 신장: \(Jin.height)")
print("이름: \(Eric.name), 나이: \(Eric.age), 신장: \(Eric.height)"
contains() = ()라는 멤버를 포함하는지 확인
firstIndex(Of:) = 해당 요소의 인덱스를 알아 낼 수 있음
append() = 맨 뒤에 요소 추가
insert() = 중간에 요소 삽입
remove() = 요소 삭제
✏️ 배열 인덱스는 0부터 시작함!
주의! 비어있는 인덱스 접근은 잘못하면 프로그램 강제 종료가 될 수 있다.
var Strings: Array<String> = Array<String>()
// String타입의 Array라는 뜻
var Strings: [String] = [String]()
var Strings: [String] = []
let immutableArray = [1, 2, 3,] // let Array는 append, remove 등과 같은 메서드는 사용 불가
// 대괄호를 사용하여 배열임을 표현함
var names: Array<String> = ["Jin", "chulsoo", "younghee", "Jack"]
// 위 선언과 정확히 동일한 표현입니다. [String]은 Array<String>의 축약 표현임.
var names: [String] = ["Jin", "chulsoo", "younghee", "Jack"]
var emptyArray: [Any] = [Any]() // Any 데이터를 요소로 갖는 빈 배열을 생성함.
var emptyArray: [Any] = Array<Any>() // 위 선언과 정확히 같은 동작을 하는 코드임.
// 배열의 타입을 정확히 명시해줬다면 []만으로도 빈 배열을 생성할 수 있음.
var emptyArray: [Any] = []
print(emptyArray.isEmpty) // true
print(names.count) // 4
print(names[2])
names[2] = "Jenny"
print(names[2])
print(names[4]) // 인덱스의 범위를 벗어낫기에 오류 발생함
names[4] = "Jan" // 인덱스의 범위를 벗어낫기에 오류 발생함
names.append("Elsa") // ["Jin", "chulsoo", "Jenny", "Jack", "Elsa"] / 맨 마지막에 Elsa 추가됨
names.append(contentsOf: ["John", "Max"]) // ["Jin", "chulsoo", "Jenny", "Jack", "Elsa", "John", "Max"]/ / 맨 마지막에 John과 Max가 추가됨
names.insert("happy", at: 2) // ["Jin", "chulsoo", "happy", "Jenny", "Jack", "Elsa", "John", "Max"] / 인덱스 2에 추가됨
names.insert(contentsOf: ["Jinhee", "Minsoo"], at: 5) // ["Jin", "chulsoo", "happy", "Jenny", "Jack", "Jinhee", "Minsoo", "Elsa", "John", "Max"] / 인덱스 5의 위치에 Jinhee와 Minsoo가 추가됨
print(names[4])
print(names.firstIndex(of: "Jin")) // "Optional(0)\n" / 인덱스 확인 : 0, 첫번째르 뜻함
print(names.firstIndex(of: "Christal")) // "nil\n" / 인덱스 확인 : 해당되는 이름의 인덱스가 없음 그래서 nil로 뜸
print(names.first) // Jin / 첫번째 인덱스 확인
print(names.last) // Max / 마지막 인덱스 확인
let firstItem: String = names.removeFirst() // ["Jin", "chulsoo", "happy", "Jenny", "Jack", "Jinhee", "Minsoo", "Elsa", "John", "Max"] 에서 첫번째인 Jin이 삭제됨
let lastItem: String = names.removeLast() // ["chulsoo", "happy", "Jenny", "Jack", "Jinhee", "Minsoo", "Elsa", "John", "Max"] 에서 마지막인 Max가 삭제됨
let indexZeroItem: String = names.remove(at: 0) //["chulsoo", "happy", "Jenny", "Jack", "Minsoo", "Elsa", "John"]에서 0번째에 있는 chulsoo가 삭제됨
print(firstItem) // Jin
print(lastItem) // Max
print(indexZeroItem) // chulsoo
print(names) // "["happy", "Jenny", "Jack", "Jinhee", "Minsoo", "Elsa", "John"] 모든 메서드를 사용후 나온 결과
removeValue(forKey: " ") = 키에 해당하는 값이 제거된 후 반환된다.
값에 'nil'을 할당해서 키를 없앨수 있음
// String이라는 키의 Any의 값을 가진다는 뜻
var anyDictionary: Dictionary<String, Any> = Dictionary<String, Any>()
var anyDictionary: Dictionary<String, Any> = [String: Any]()
var anyDictionary: [String: Any] = [String: Any]()
var anyDictionaty: StringAnyDictionary = StringAnyDictionary()
typealias anyDictionaty = [String: Any] // typealias(타입 별칭)를 통해 더 단순하게 표현 가능함
let initalizedDictionary: [String: String] = ["name": "jin", "gender": "male"]
//let으로 name이라는 키에 jin이라는 값이 할당되어있음
let someValue: String = initalizedDictionary["name"]
//딕셔너리의 키인 "name"에 해당하는 값이 있을 수도 있고 없을수도 있는 그런 불확실성에 의해 작동 되지 않음. 이건 옵셔널에서 더 다룰 예정.
//키는 String, 값은 Int 타입인 빈 딕셔너리를 생성
var numberForName: Dictionary<String, Int> = Dictionary<String, Int>()
// 딕셔너리의 키와 값을 정확히 명시했다면 [:]만으로도 빈 딕셔너리를 생성 가능함
var numberForName: [String: Int] = ["jin": 100, "chulsoo": 200, "jenny":300]
print(numberForName.isEmpty) //false
print(numberForName.count) // 3
// [딕셔너리의 사용]---------
print(numberForName["chulsoo"])
print(numberForName["minji"])
numberForName["chulsoo"] = 150 // 원래의 값 200을 150으로 바꿈
print(numberForName["chulsoo"])
numberForName["max"] = 999 // max라는 키로 999라는 값을 추가함
print(numberForName["max"]) // 999
print(numberForName.removeValue(forKey: "jin"))
// 위에서 jin에 해당하는 값이 이미 삭제되었으므로 nil로 변환됨
// 키에 해당하는 값이 없으면 기본값으로 돌려주게 되어 있음
print(numberForName.removeValue(forKey: "jin"))
// jin 키에 해당하는 값이 없으면 기본으로 0으로 반환됨
print(numberForName["jin", default: 0])
contains() : 요소 확인
count() : 요소 카운트
insert() : 요소 추가
remove() : 요소 삭제 후 반환
let setA: Set<Int> = [1, 2, 3, 4, 5]
let setB: Set<Int> = [3, 4, 5, 6, 7]
// 집합 메서드
let sortedUnion: [Int] = union.sorted()
// 같은 타입의 배열로 바뀜 [1,2,3,4,5,6,7]
let union: Set<Int> = setA.union(setB) // 합집합 {2,4,5,6,7,3,1,} 위랑 순서가 다르게 값이 나옴
let intersection: Set<Int> = setA.intersection(setB) // 교집합
let subtraction: Set<Int> = setA.subtraction(setB) // 차집합
var names: Set<String> = Set<String>() // 빈 세트 생성
var names: Set<String> = [] // 위 코드와 정확히 같음.
// Array와 마찬가지로 대괄호를 사용
var names: Set<String> = ["jin", "chulsoo", "younghee", "jin"]
// 그렇기에 타입 추론을 사용하면 컴파일러는 Set가 아닌 Array 타입으로 지정함
var numbers = [100, 200, 300]
print(type(of: numbers)) // Array<Int>로 나옴
print(names.isEmpty) // false
print(names.count) // 중복된 값(jin이 2개)은 허용되지 않아 4개가 아니라 3임
names.insert("jenny")
print(names.count)
print(names.remove("chulsoo")) // chulsoo 삭제
print(names.remove("john")) // nil
// [세트의 활용 - 집합연산]---------
let EnglishClassStudent: Set<String> = ["john", "chulsoo", "jin"]
let KoreanClassStudnet: Set<String> = ["jenny", "jin", "chulsoo", "hana", "minsoo"]
// 1. 교집합 = jin, chulsoo
let intersectSet: Set<String> = EnglishClassStudent.intersection(KoreanClassStudnet)
// 2. 여집합의 합(배타적 논리합) = john, jenny, hana, minsoo
let symmetricDiffset: Set<String> = EnglishClassStudent.symmetricDifference(KoreanClassStudnet)
// 3. 합집합 = minsoo, jenny john, jin, chulsoo, hana
let unionSet: Set<String> = EnglishClassStudent.union(KoreanClassStudnet)
// 4. 차집합 = john
let subtractSet: Set<String> = EnglishClassStudent.subtracting(KoreanClassStudnet)
// 4.1 차집합 순서 변경으로 값의 변화 = jenny, minsoo, hana
let subtractSet: Set<String> = KoreanClassStudnet.subtracting(EnglishClassStudent)
- 세트의 활용 - 포함관계 연산
let 새: Set<String> = ["비둘기", "닭", "기러기"]
let 포유류: Set<String> = ["사자", "호랑이", "곰"]
let 동물: Set<String> = 새.union(포유류) // 새와 포유류의 합집합
print(새.isDisjoint(with: 포유류)) // 서로 배타적인지 - true
print(새.isSubset(of: 동물)) // 새가 동물의 부분집합인가? - true
print(동물.isSuperset(of: 포유류)) // 동물은 포유류의 전체집합인가? - true
print(동물.isSuperset(of: 새)) // 동물은 새의 전체집합인가? - true
enum MediaType
case audio
case video
var mediaType: MediaType = .audio
enum School {
case primary
case elementary
case middle
case high
case college
case university
}
// 각 항목은 그 자체가 고유의 값이며, 한 줄에 모두 표현 가능하다.
enum School {
case primary, elementary, middle, high, college, university
}
// 열거형 변수의 생성 및 값 변경
var highestEducationLevel: School = School.university
// 위 코드와 같은 표현
var highestEducationLevel: school = .university
// 같은 타임인 School 내부의 항복으로만 highestEducationLevel의 값을 변경 가능함
highestEducationLevel = .graduate
let highestEducationLevel: School = School.university
print ("저의 최종학력은 \(highestEducationLevel.rawValue) 졸업입니다.")
enum School : String {
case primary = "유치원"
case elementary = "초등학교"
case middle = "중학교"
case high = "고등학교"
case college = "대학"
case university = "대학교"
}
let highestEducationLevel: School = School.university
print ("저의 최종학력은 \(highestEducationLevel.rawValue) 졸업입니다.")
// 열거형의 원시 값 일부 지정 및 자동처리
enum School : String {
case primary = "유치원"
case elementary = "초등학교"
case middle = "중학교"
case high = "고등학교"
case college
case university
}
print(School.elementary.rawValue)
enum Numbers: Int {
case zero
case one
case two
case ten = 10 // 값을 안 정해주면 3으로 나옴
}
print("\(Numbers.zero.rawValue), \(Numbers.one.rawValue), \(Numbers.two.rawValue), \(Numbers.ten.rawValue)")
// 원시 값을 통한 열거형 초기화
let primary = School(rawValue: "유치원") // primary / 열거형이 원시 값을 갖는 열거형일 때, 원시형의 원시 값을 통해 열거형 변수 또는 상수 생성 가능
let university = School(rawValue: "대학교") // 올바르지 않은 원시 값을 통해 생성하려면 nil로 반환함.
let one = Numbers(rawValue: 1) // one
let three = Numbers(rawValue: 10) // nil
let zero: String = "hello"
print(Numbers.zero.rawValue) // 열거형 추가/ 수정 불가
enum MainDish {
case pasta(taste: String)
case pizza(dough: String, topping: String)
case chicken(withSauce: Bool)
case rice
}
var dinner: MainDish = MainDish.pasta(taste: "크림")
dinner = .pizza(dough: "치즈크러스트", topping: "불고기")
dinner = .chicken(withSauce: true)
dinner = .rice
enum PastaTaste {
case cream, tomato
}
enum PizzaDough {
case cheeseCrust, thin, original
}
enum PizzaTopping {
case pepperoni, cheese, bacon
}
enum MainDish{
case pasta(taste: PastaTaste)
case pizza(dough: PizzaDough, topping: PizzaTopping)
case chicken(withSauce: Bool)
case rice
}
var dinner: MainDish = MainDish.pasta(taste: PastaTaste.tomato)
dinner = MainDish.pizza(dough: PizzaDough.cheeseCrust, topping: PizzaTopping.bacon)
let allCases: [School] = School.allCases
print(allCases)
// School.primary, School.elementary, School.middle, School.high, School.college, School.university
// 원시값을 갖는 열거형의 항목순회
enum School: String, CaseIterable {
case primary = "유치원"
case elementary = "초등학교"
case middle = "중학교"
case high = "고등학교"
case college = "대학"
case university = "대학교"
}
let allCases: [School] = School.allCases
print(allCases)
// School.primary, School.elementary, School.middle, School.high, School.college, School.university
<br/>
### 5.5. 순환 열거형
- indirect 키워드를 사용한다.
- 특정 항목에만 적용하고 싶다면 case 키워드 앞에 indirect, 열거형 전체에 적용하고 싶으면 enum 키워드 앞에 indirect를 붙이면 된다.
<br/>
- 특정 항목에 순환 열거형 항목 명시
```swift
enum ArithmeticExpression {
case number(Int)
indirect case addition(ArithmeticExpression, ArithmeticExpression)
indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}
indirect enum ArithmeticExpression {
case number(Int)
case addition(ArithmeticExpression, ArithmeticExpression)
case multiplication(ArithmeticExpression, ArithmeticExpression)
}
enum Condition: Comparable {
case terrible
case bad
case good
case great
}
let myCondition: Condition = Condition.great
let yourCondition: Condition = Condition.bad
if myCondition >= yourCondition {
print("제 상태가 더 좋군요")
} else {
print("당신의 상태가 더 좋아요")
}
// 제 상태가 더 좋군요 //
enum Device: Comparable {
case iPhone(version: String)
case iPad(version: String)
case macBook
case iMac
}
var devices: [Device] = []
devices.append(Device.iMac)
devices.append(Device.iPhone(version: "14.3"))
devices.append(Device.iPhone(version: "6.1"))
devices.append(Device.iPad(version: "10.3"))
devices.append(Device.macBook)
let sortedDevices: [Device] = devices.sorted()
print(sortedDevices)
// [Device.iPhone(version: "14.3"), Device.iPhone(version: "6.1"), Device.iPad(version: "10.3"), Device.iMac]