// 자주 사용하는 메서드
// Array
var numbers: [Int] = [1, 2, 3]
let count: Int = numbers.count // 배열 갯수 확인 : 3
let isEmpty: Bool = numbers.isEmpty // 배열 비었는지 확인 : false
numbers[0] // 1
numbers[0...1] // [1, 2]
numbers.first // Optional(1)
numbers.last // Optional(3)
numbers.append(4) // [1, 2, 3, 4]
numbers.append(contentsOf: [5, 6, 7]) // [1, 2, 3, 4, 5, 6, 7]
numbers.insert(0, at: 0) // [0, 1, 2, 3, 4, 5, 6, 7]
numbers.insert(contentsOf: [10, 100], at: 2) // [0, 1, 10, 100, 2, 3, 4, 5, 6, 7]
numbers.remove(at: 2) // [0, 1, 100, 2, 3, 4, 5, 6, 7]
numbers.removeFirst() // [1, 100, 2, 3, 4, 5, 6, 7]
numbers.removeLast() // [1, 100, 2, 3, 4, 5, 6]
numbers.popLast() // [1, 100, 2, 3, 4, 5]
numbers.removeSubrange(1...3) // [1, 4, 5]
numbers.removeAll() // []
// Array - 비교
var array1 = [1, 2, 3]
var array2 = [1, 2, 3]
var array3 = [1, 2, 3, 4, 5]
array1 == array2 //true
array1.elementsEqual(array3) //false
// Array - 정렬
let unsorted = [1, 5, 3, 8, 6, 10, 14]
unsorted.sort() // unsorted 배열을 오름차순 정렬 [1, 3, 5, 6, 8, 10, 14]
unsorted.sort(by: >) // unsorted 배열을 내림차순 정렬 [14, 10, 8, 6, 5, 3, 1]
let sortedArray = unsorted.sorted() // unsorted 배열을 오름차순 정렬하여 반환 [1, 3, 5, 6, 8, 10, 14]
let sortedArray2 = unsorted.sorted(by: >) // unsorted 배열을 내림차순 정렬하여 반환 [14, 10, 8, 6, 5, 3, 1]
// Dictionary
var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
airports.keys // ["YYZ", "DUB"]
airports.values // ["Toronto Pearson", "Dublin"]
airports.keys.sorted() // ["DUB", "YYZ"]
airports.values.sorted() // ["Dublin", "Toronto Pearson"]
airports["APL"] = "Apple International" // airports = ["YYZ": "Toronto Pearson", "DUB": "Dublin", "APL": "Apple International"]
airports["APL"] = nil // key에 매칭된 value 값 초기화
print(airports.count) // airports.count는 2
print(airports.keys) // 딕셔너리 airports에 있는 모든 key들. 딕셔너리 airports에 있는 모든 key들
let newYyz = airports.updateValue("Hello YYZ", forKey: "YYZ") // 해당 key가 있다면 value를 덮어쓰고, 덮어쓰기 전 기존값울 반환
print(newYyz) // 출력값: Optional("Toronto Pearson")
print(airports["YYZ"]) // 출력값: Optional("Hello YYZ")
let newApl = airports.updateValue("Hello APL", forKey: "APL") // 해당 key가 없다면 그 key에 해당하는 value에 값을 추가하고 nil을 반환
print(newApl) // 출력값: nil
print(airports["APL"]) // 출력값: Optional("Hello APL")
// Set
var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]
favoriteGenres.isEmpty // false
favoriteGenres.count // 3
favoriteGenres.contains("Rock") // true
favoriteGenres.randomElement() // Hip hop (다른 element가 나올 수 있음)
favoriteGenres.remove("Rock") // "Rock" -> 삭제된 요소를 리턴
favoriteGenres // ["Classical", "Hip hop"]
favoriteGenres.remove(5) // nil -> 존재하지 않는 요소를 삭제했을 때 에러는 발생하지 않고 nil 리턴
favoriteGenres.removeAll() // []
let oddDigits: Set = [1, 3, 5, 7, 9]
let evenDigits: Set = [0, 2, 4, 6, 8]
let singleDigitPrimeNumbers: Set = [2, 3, 5, 7]
// Set - 합집합
oddDigits.union(evenDigits).sorted() // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
// Set - 교집합
oddDigits.intersection(evenDigits).sorted() // []
// Set - 차집합
oddDigits.subtracting(singleDigitPrimeNumbers).sorted() // [1, 9]
// Set - 대칭 차집합
oddDigits.symmetricDifference(singleDigitPrimeNumbers).sorted() // [1, 2, 9]
Step 3의 'Lv1 - 2. 성적 관리 시스템 제작하기' 과제에서 제공해준 예시이다.
오늘은 이 예시를 가지고 Array, Dictionary, Set 에 대해서 공부해보았다.
Array 메소드 - .removeLast
와 .popLast
의 차이
removeLast()
: 배열의 마지막 요소를 제거하고, 그 요소를 반환한다. 배열이 비어있으면 오류(runtime error)를 발생시킨다.popLast()
: 배열의 마지막 요소를 제거하고, 그 요소를 옵셔널(Optional)로 반환한다. 배열이 비어 있을 경우, nil을 반환하고 오류는 발생하지 않는다.Array 비교 - ==
연산자와 elementsEqual()
메소드 이용의 차이
==
연산자는 배열의 모든 요소뿐만 아니라, 배열의 길이도 비교한다.elementsEqual()
메소드는 배열의 각 요소의 순서대로 비교한다.Array
를 비교할 때 성능과 최적화 측면에서는 ==
연산자가 더 효율적일 수 있다.==
는 두 배열의 길이가 같지 않을 때 비교를 시작하기 전 바로 false
를 반환한다.elemtnsEqual()
메소드는 Array
뿐만 아니라 String
(Chracter
의 시퀀스), Range
, Dictionary
등 다양한 시퀀스를 비교할 수 있다.elementsEqual()
메소드는 순차적으로 비교하기 때문에 시퀀스의 순서가 중요하다.Set
는 그래서 해당 메소드를 사용할 수 없고 ==
연산자를 사용해 비교해야 한다.Dictionary
또한 순서가 없는 컬렉션이지만, Swift 5.0 부터는 삽입된 순서가 유지된다. 키-값 쌍이 삽입된 순서대로 시퀀스처럼 비교하게 되나, 본래 Dictionary
는 순서가 없는 컬렉션으로 설계되었기에 순서에 의존하는 비교 방식은 안전하지 않다.let
으로 선언한 배열의 특징
배열 자체의 변경 불가: let
으로 선언된 배열은 배열 자체를 새로운 배열로 할당하거나, 배열의 참조를 변경할 수 없다.
var
로 선언한 배열과는 다르게, let
으로 선언한 배열은 한 번 설정된 참조, 즉 메모리의 위치를 변경할 수 없다.배열 내부의 요소는 수정 가능: 배열이 가변적인 구조이기 때문에, 배열의 요소를 추가하거나 제거할 수 있다. Swift에서 배열은 값 타입이지만, 내부적으로 let 배열의 내용물(요소)은 변할 수 있는 가변적인 특성을 유지한다.
배열 내부의 요소 수정 불가:
let numbers = [1, 2, 3, 4]
// 배열의 요소 추가 (불가능)
// numbers.append(5) // 컴파일 에러: 'numbers'는 let 상수이므로 수정할 수 없습니다.
// 배열의 요소 제거 (불가능)
// numbers.remove(at: 1) // 컴파일 에러: 'numbers'는 let 상수이므로 수정할 수 없습니다.
// 배열의 요소 수정 (불가능)
// numbers[0] = 10 // 컴파일 에러: 'numbers'는 let 상수이므로 수정할 수 없습니다.
Set
을 선언할 때 데이터 타입을 지정하지 않는 경우
Set
안의 데이터 타입이 추론되는 여러가지 방식
초기화할 때의 타입 추론
let favoriteGenres = Set(["Rock", "Classical", "Hip hop"])
// 타입 추론에 의해 favoriteGenres는 Set<String>으로 결정됨
타입이 명확할 때
let oddDigits: Set = [1, 3, 5, 7, 9]
// oddDigits는 Set<Int>로 추론됨
타입을 사용하는 함수 또는 메서드
let favoriteGenres: Set = ["Rock", "Classical", "Hip hop"]
if favoriteGenres.contains("Rock") {
print("We have Rock!")
}
타입을 제약하는 제네릭 메서드
let evenDigits: Set = [0, 2, 4, 6, 8]
let primes: Set = [2, 3, 5, 7]
let commonElements = evenDigits.intersection(primes)
// commonElements는 Set<Int>로 추론됨
(제네릭 메서드가 뭔지는 일단 생략..)
선언과 초기화의 차이
Set
선언var favoriteGenres: Set<String> // String 타입의 Set을 선언함. 현재는 빈 집합.
Set
초기화favoriteGenres = ["Rock", "Classical", "Hip hop"] // 값을 할당하여 초기화
Set
의 선언과 초기화를 동시에 수행var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]
Set
을 선언 및 초기화하는 방식
Set()
메서드 사용var emptySet1: Set<Int> = Set() // 빈 Int 집합
[]
배열 구문 사용var emptySet2: Set<String> = [] // 빈 String 집합
당연한 얘기지만, []
를 사용해 Set를 초기화가 가능한 것은 앞의 'Set = ' 의 맥락이 있기에 가능한 것.[]
는 배열 등에서도 사용되기에 Set()
메서드를 사용하는 것과는 맥락적 차이가 있음.Set
로 선언된 후 값이 초기화된다는 걸 인식하면 크게 헷갈릴 일은 없을 것 같다.var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"] // 문자열 집합 초기화
Set
초기화 메서드 사용var favoriteGenresUsingMethod: Set<String> = Set(["Rock", "Classical", "Hip hop"]) // 문자열 집합 초기화
(문제 풀이는 이 글에서 계속)