1. Array
배열의 정의
- swift에서 가장 일반적으로 사용되는 자료구조 중 하나
- 동일한 유형의 값의 순서가 있는 콜렉션 타입
- 각 요소는 인덱스를 사용해 접근 가능
배열의 선언과 초기화
- 대괄호([]) 기호를 사용하여 빈 배열을 선언
var numbers: [Int] = []
var numbers = [Int]()
- 대괄호([]) 안에 값을 쉼표로 구분하여 나열
var numbers = [1, 2, 3, 4, 5]
- 배열을 초기화 할 때, 타입 어노테이션(type annotation)을 사용하여 배열의 타입 지정 가능
var numbers: [Int] = [1, 2, 3, 4, 5]
- Swift는 타입 추론(type inference)을 지원하기 때문에, 타입을 생략할 수 있음
- 초기값을 기반으로 배열의 타입을 추론
var numbers = [1, 2, 3, 4, 5] // numbers의 타입은 [Int]로 추론됩니다.
- 배열에 다른 타입의 요소들을 저장하는 혼합배열 또는 Any 배열을 생성 가능
- 가능한 모든 요소가 동일한 유형의 배열을 사용하는것이 좋음
var mixedArray = [1, "two", 3.0]
배열 요소 접근
- 인덱스(index)를 사용하여 배열의 요소에 접근
- 배열의 인덱스는 0부터 시작
var numbers = [1, 2, 3, 4, 5]
let firstNumber = numbers[0] // 1 let secondNumber =numbers[1] // 2
- 배열의 마지막 요소에 접근하려면 count 속성을 사용하여 배열의 길이를 가져온 후, 인덱스는 count-1로 설정
let lastNumber = numbers[numbers.count-1]
let n = [1, 2, 3]
print(n[1..<2]) //2
print(n[1...2]) //2, 3
- 특정 인덱스를 찾기 위해서는 firstIndex(of: ) 메서드를 사용
- 배열에 동일한 요소가 있는 경우, 더 작은 인덱스를 반환
- optional 값으로 반환
var arr = [1,2,3,4,5]
arr.firstIndex(of: 1) //Optional(0)
배열에 요소 추가
- 새로운 요소를 배열에 추가하기 위해서는, append() 메서드를 사용
var numbers = [1, 2, 3, 4, 5]
numbers.append(6) // 6을 배열의 마지막 요소로 추가합니다.
- 특정 위치에 요소를 추가하기 위해서는, insert() 메서드를 사용
- insert를 하는 위치부터 배열을 재배치 해야 하기 때문에 오버헤드가 발생
- 가능한 append 사용
var arr = [1, 2, 3, 4, 5]
arr.insert(10, at: 3) //10을 배열의 3번째에 추가합니다.
print(arr) //[1, 2, 3, 10, 4, 5]
배열의 수정
- 배열의 요소를 수정하기 위해서는 인덱스를 사용하여 해당 요소에 접근한 후, 값을 변경
var numbers = [1, 2, 3, 4, 5]
numbers[2] = 30 // 세 번째 요소를 30으로 변경합니다.ㄱㄷ배
- 배열의 특정 범위의 값을 수정하고 싶을 때 replaceSubrange 를 사용하여 값을 변경 가능
var array2 = [1, 2, 3]
array2.replaceSubrange(0...2, with: [10, 20, 30]) // [10, 20, 30]
array2.replaceSubrange(0...2, with: [0]) // [0]
array2.replaceSubrange(0..<1, with: []) // []
배열의 삭제
- 배열의 요소를 삭제하기 위해서는, remove() 메서드를 사용
var numbers = [1, 2, 3, 4, 5]
numbers.remove(at: 2) // 세 번째 요소를 삭제합니다.
numbers.removeFirst() //배열의 첫 번째 요소를 삭제합니다.
numbers.removeLast() //배열의 마지막 요소를 삭제합니다.
numbers.removeAll() //배열의 모든 요소를 삭제합니다.
함수 이름 | 용도 | 리턴 타입 |
remove(at:) | 파라미터로 받은 index에 해당하는 값 삭제 | 삭제된 값 리턴Non-Optional Type |
removeFirst | 첫 번째 요소 삭제 | 삭제된 값 리턴Non-Optional Type |
removeFirst(_:) | 첫 번째 요소부터 파라미터로 받은 갯수 만큼 삭제 | X |
removeLast | 마지막 요소 삭제 | 삭제된 값 리턴Non-Optional Type |
popLast | 마지막 요소 삭제 | 삭제된 값 리턴Non-Optional Type |
removeLast(_:) | 마지막 요소부터 파라미터로 받은 갯수 만큼 삭제 | X |
removeAll | 전체 요소 삭제 | X |
removeSubrange(_:) | 파라미터로 받은 범위만큼 index 요소 삭제 | X |
[n...m] = [] |
Subscript 문법으로 n ~ m까지 index 요소 삭제 | X |
배열의 기타 기능
max() | 배열의 최대값 반환 |
min() | 배열의 최소값 반환 |
sort() | 배열을 오름차순으로 정렬 |
sort(by: >) | 배열을 내림차순으로 정렬 |
isEmpty | 배열이 비어있는지 확인 |
elementsEqual(arr) | 다른 배열과 같은 배열인지 비교 |
contains(n) | 배열에 n이 존재하는지 확인 |
swapAt(a, b) | 인덱스 a의 요소와 인덱스 b의 요소를 변경 |
2. Dictionary
Dictionary의 정의
- 딕셔너리는 키(Key) 와 값(Value)의 쌍으로 구성되는 순서가 없는 자료구조
- 딕셔너리에서 key는 value를 대변하는 유일한 식별자가 됨
- 딕셔너리 안에는 같은 이름을 가진 key가 존재하지 않음(유일성)
- 딕셔너리 안에서 value는 유일하지 않음
- 각 value는 key로 접근이 가능
- 딕셔너리 내부에 존재하지 않는 key로 접근하게 되면 nil 값을 반환
Dictionary의 선언
- 대괄호([]) 안에 key와 value의 쌍들을 넣어 초기화
/*
var [딕셔너리 이름]: Dictionary<키 타입, 값 타입> = Dictionary<키 타입, 값 타입>()
*/
// Dictionary 선언
var anyDictionary: Dictionary<String, Int> = [String: Int]()
// 동일 표현 - 리터럴 이용
var anyDictionary: Dictionary<String, Any> = Dictionary<String, Any>()
var anyDictionary: Dictionary<String, Any> = [:]
var anyDictionary: [String: Any] = Dictionary<String, Any>()
var anyDictionary: [String: Any] = [String: Any]()
// 동일 표현 - 빈 딕셔너리 생성
var anyDictionary: [String: Any] = [:]
var anyDictionary = [String: Any]()
// 초기화
var anyDictionary: [String: Int] = ["extramilejin": 28, "korea": 2021]
Dictionary의 value 설정
- 딕셔너리의 value에 접근하는 가장 흔한 방법은 key를 subscript로써 사용
- 딕셔너리에서 key에 해당하는 값이 없을 수 있기 때문에, 반환 값은 optional 인스턴스
- subscript
var responseMessages = [200: "OK",
403: "Access forbidden",
404: "File not found",
500: "Internal server error"]
print(responseMessages[200])
// Optional("OK")
- if let 구문을 사용하여 딕셔너리에서 key에 해당하는 값의 유무에 따라 다른 동작을 수행
let httpResponseCodes = [200, 403, 301]
for code in httpResponseCodes {
//key에 해당하는 값 존재
if let message = responseMessages[code] {
print("Response \\(code): \\(message)")
}
//key에 해당하는 값 없음
else {
print("Unknown response \\(code)")
}
}
// Prints "Response 200: OK"
// Prints "Response 403: Access forbidden"
// Prints "Unknown response 301"
Dictionary 추가, 삭제, 수정
- subscripting을 사용하여 key와 value를 추가, 삭제, 수정을 할 수 있음
- 새로 추가하는 key-value pair은 dictionary에 존재하지 않는 key-value로 추가해야함 (키는 유일성 보장)
- key-value pair 삭제는 삭제하고자하는 key에 해당하는 value를 nil로 수정하면 영구적으로 삭제됨
// add key-value pair
responseMessages[301] = "Moved permaently"
print(responseMessages[301])
// Prints Optional("Moved permaently")
// update key-value pair
responseMessages[301] = "Deleted permanently"
print(responseMessages[301])
// Prints Optional("Deleted permanently")
// remove key-value pair
responseMessages[500] = nil
print(responseMessages)
// Prints [200: "OK", 301: "Deleted permanently", 403: "Access forbidden", 404: "File not found"]
responseMessages.removeValue(forKey: 404)
responseMessages.removeAll()
Dictionary의 프로퍼티와 메서드
- isEmpty: 딕셔너리가 비어있다면 true, 비어있지 않다면 false 반환
- count : 딕셔너리의 요소의 개수를 반환
- removeValue(forKey: ) : key에 해당하는 value를 찾아 제거하고 그 값을 반환
- 만약 딕셔너리 안에 key에 해당하는 value가 없다면 nil을 반환
- 이 경우 기본값을 돌려주는 것도 가능
- keys: 딕셔너리 안에 있는 모든 key를 배열로 반환
- values: 딕셔너리 안에 있는 모든 value를 배열로 반환
- contains(where:): 딕셔너리에 요소가 존재하면 true, 아니라면 false 반환
- firstIndex(where:): 딕셔너리에 해당 요소의 첫 번째 인덱스를 optional로 반환
- 딕셔너리이름 [ 키 ] = 값 : 딕셔너리에 키 와 값을 쌍을 추가
- 딕셔너리이름 [ 키 ] = nil : 딕셔너리에서 키에 해당하는 값을 nil로 할당하여 제거
var intDictionary: [String: Int] = ["extramilejin": 28, "korea": 2021]
print(intDictionary.isEmpty) // false
print(intDictionary.count) // 2
print(intDictionary.removeValue(forKey: "korea")) // Optional(2021)
print(intDictionary.count) // 1
print(intDictionary.removeValue(forKey: "korea")) // nil: 값이 없음을 뜻한다.
print(intDictionary["korea", default: 0]) // 0: 값이 없으면 기본값 0
let countryCodes = ["BR": "Brazil", "GH": "Ghana", "JP": "Japan"]
print(countryCodes.keys) //["GH", "JP", "BR"]
print(countryCodes.values) //["Ghana", "Japan", "Brazil"]
print(countryCodes.contains(where: {$0.value == "Brazil"})) //true
Dictionary의 기본 값
- 존재하지 않는 key를 사용하여 딕셔너리에서 value를 읽으려고하면 nil을 반환
- 존재하지 않는 key에 대한 value를 요청하는 경우 기본값을 미리 할당할 수 있음
- 딕셔너리에서 value에 증감 연산(+= 1, -= 1 … )을 하는 경우 사용
let favoriteIceCream = [ "서근": "초콜릿", "포뇨": "바닐라" ]
favoriteIceCream["서근"]
favoriteIceCream["하울"] // nil이 반환됨 -> 이는 해당 키에 대한 값이 없음을 의미함
//딕셔너리에 "Unknown"의 **기본값**을 지정하여이 nil이 반환되는 것을 방지
favoriteIceCream["하울", default: "Unknown"]
Dictionary의 반복
- 딕셔너리 내부를 순회하기 위해, for-in loop를 사용해, key-value 쌍을 얻어 순회
- key-value쌍은 튜플 형태로 반환
let imagePaths = ["star": "/glyphs/star.png",
"portrait": "/images/content/portrait.jpg",
"spacer": "/images/shared/spacer.gif"]
for (name, path) in imagePaths{
print("The path to '\\(name)' is '\\(path)'.")
}
// The path to 'spacer' is '/images/shared/spacer.gif'.
// The path to 'star' is '/glyphs/star.png'.
// The path to 'portrait' is '/images/content/portrait.jpg'.
3. enum
enum의 정의
- 열거형은 관련된 값 들의 그룹을 정의할 수 있도록 해주는 데이터 타입
- 코드의 가독성과 안전성을 높여줌
- 각기 다른 상태와 각기 다른 타입의 입력값을 나타내기 위해 사용
enum Direction {
case north
case south
case east
case west
}
- 각 case에 대한 추가적인 정보 부여 가능
enum HTTPResponse {
case success(Int)
case error(Int, String)
}
enum의 역할 및 필요성
- 가독성
- 관련 값에 의미 있는 이름을 지정할 수 있으므로 코드를 더 읽기 쉽고 쉽게 이해할 수 있음
- 안전성
- 서로 다른 타입의 값이 잘못 변경되지 않도록함으로 형 안전성(type-safety)을 제공함
- ex- Monday 타입의 값이 String 타입이 예상되는 곳에 잘못 사용되지 않도록 할 수 있음
- 단순화
- 열거형을 사용하면 작성해야 하는 코드의 양을 줄이고 코드를 보다 간결하게 만들 수 있음
- 여러 개의 상수 또는 변수 선언을 단일 열거형 선언으로 대체 할 수 있음
- 조직
- 관련 값들을 열거형으로 그룹화하면 코드를 보다 효율적으로 구성할 수 있고 유지 관리도 쉽게 할 수 있음
- 값 매칭
- Swift의 스위치 구문은 열거형과의 값 매칭을 지원하므로 특정 값의 다양한 케이스를 쉽게 처리할 수 있음
- 가능한 많은 수의 사례를 처리해야 할 때 특히 유용할 수 있음
enum HTTPResponse {
case success(Int)
case error(Int, String)
}
let response = HTTPResponse.success(200)
switch response {
case .success(let statusCode):
print("Success with status code \\(statusCode)")
case .error(let statusCode, let message):
print("Error with status code \\(statusCode) and message \\(message)")
}
enum의 사용법
enum Direction {
case north
case south
case east
case west
}
// To use an enum value, you simply reference its name:
let direction = Direction.north
switch direction {
case .north:
print("Heading north")
case .south:
print("Heading south")
case .east:
print("Heading east")
case .west:
print("Heading west")
}
- enum 키워드를 사용해 열거형 정의
- 여러 케이스를 콤마(,)로 구분하여 한 줄에 적을 수 있음
- 완전 새로운 형 정의해야 함
- Planet
- 대문자로 시작해야 함
enum Planet { case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune }
- 형이 이미 한 번 정의된 경우, 다음에 값을 할당할 때에는 형을 생략한 점문법(dot syntax)을 이용해 값을 할당할 수 있음
var whereToGo = Planet.earth
whereToGo = .mercury
4. Set
Set의 정의
- 같은 데이터 타입의 값을 순서 없이 저장하는 리스트
- 중복을 허용하지 않음
var setName: Set = Set<Int>()
Set의 사용
count | set의 항목의 개수 반환 |
isEmpty | set이 비어있는지 확인 |
insert(value) | set에 값 추가 |
remove(value) | set에서 값 삭제 |
contains(value) | set에 값이 존재하는지 확인 |
intersection(b) | set b와 같은 요소들만 반환, 교집합 |
union(b) | set b의 요소와 set의 요소 모두 부분 반환, 합집합 |
symmetricDifference(b) | set b의 요소와 set의 요소에서 같은 요소만 빼고 반환 |
subtracting(b) | set의 요소에서 set b와 같은 요소만 빼고 반환 |
반응형
'⌨️ Language > swift' 카테고리의 다른 글
[Swift] 예외 처리와 함수 (4) | 2024.03.17 |
---|---|
[Swift] 조건/반복문 (1) | 2024.03.17 |
[Swift] 변수와 프로퍼티2 (1) | 2024.03.15 |
[Swift] 변수와 프로퍼티1 (0) | 2024.03.15 |
[Swift] Escaping Closure (1) | 2023.05.20 |
댓글