SMALL
* 배열, 세트, 딕셔너리 자료구조 활용 *
* 배열 *
Array의 특징
배열(Array)은 동일한 타입의 요소들을 저장하는 순서가 있는 컬렉션
배열은 특정 요소의 인덱스를 사용하여 접근하고 수정할 수 있으며,
배열의 크기는 동적으로 조절됩니다.
인덱스(index)는 0 부터 시작
처음 선언할 때(초기화할 때) 배열의 길이를 미리 지정할 필요 X
[ 배열을 생성하는 방법 ]
// 배열 생성하기
// 1. 타입 추론으로 생성하기
var array1 = [1, 2, 3]
var array2 = [] // error! 타입 추론으론 빈 배열 생성 불가 -> 배열이 비어서가 아닌 타입을 쓰지 않아서..
// 2. 타입 Annotation으로 생성하기
var array3: [Int] = [1, 2, 3]
var array4: [Int] = [] //빈 배열 생성
// 3. 생성자로 생성하기
var array5 = Array<Int>()
var array6 = [Int]()
var array7 = [Int](repeating: 0, count: 10) //생성과 동시에 10개 Element 생성 및 0으로 초기화
[ 배열을 갯수를 확인하는 방법 ]
// 배열 갯수 확인하기
var array1 = [1, 2, 3]
let count: Int = array1.count // 배열 갯수 확인 : 3
let isEmpty: Bool = array1.isEmpty // 배열 비었는지 확인 : false
[ 배열 요소에 접근 하는 방법 ]
// 배열 요소에 접근하기
var array1 = [1, 2, 3]
// 1. Subscript로 접근하기
/*
0번부터 시작
*/
array1[0] // 1
array1[1] // 2
array1[2] // 3
// 2. 범위로 접근하기
// 범위로 접근시 0부터 1까지인 것 입니다.
array1[0...1] // [1, 2]
// 3. 속성으로 접근하기
array1.first // Optional(1)
array1.last // Optional(3)
// Tip : 왜 Optional값으로 가져와지느냐? -> 배열이 비었을 수 있기 때문입니다.
// 만약에 배열이 비었다면 nil이겠죠?!
[ 배열에 요소를 추가하는 방법 ]
// 배열에 요소 추가하기
// 1. append : 끝에 추가
var array1 = [1, 2, 3]
array1.append(4) // [1, 2, 3, 4]
array1.append(contentsOf: [5, 6, 7]) // [1, 2, 3, 4, 5, 6, 7]
// 2. inset : 중간에 추가
var array2 = [1, 2, 3]
array2.insert(0, at: 0) // [0, 1, 2, 3]
array2.insert(contentsOf: [10, 100], at: 2) // [0, 1, 10, 100, 2, 3 ]
[ 배열에 요소를 변경하는 방법 ]
// 배열에 요소 변경하기
// 1. Subscript로 변경하기
var array1 = [1, 2, 3]
array1[0] = 10 // [10, 2, 3]
array1[0...2] = [10, 20, 30] // [10, 20, 30]
array1[0...2] = [0] // [0]
array1[0..<1] = [] // [] 6번째 줄에서 길이를 1로 줄여버렸기 때문에 전체가 빈배열로 치환됨
// 2. replaceSubrange로 바꾸기 (범위 변경 시)
var array2 = [1, 2, 3]
array2.replaceSubrange(0...2, with: [10, 20, 30]) // [10, 20, 30] 0부터 2까지면 사실상 전체를 의미
array2.replaceSubrange(0...2, with: [0]) // [0] 0의 배열로변경
array2.replaceSubrange(0..<1, with: []) // [] 0부터 1미만으로 1개인 상태이기에 사실상 전체를 빈배열로 바꿔준다의 의미입니다.
[ 배열의 요소를 삭제하는 방법 ]
// 배열에 요소 삭제
// 1. 일반적인 삭제하기
var array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
array1.remove(at: 2) // [1, 2, 4, 5, 6, 7, 8, 9] 'at'은 위치를 표시하는 것 'at:2'는 3번째 값을 의미합니다.
array1.removeFirst() // [2, 4, 5, 6, 7, 8, 9] 'removeFirst' 첫번째 값을 제거
array1.removeFirst(2) // [5, 6, 7, 8, 9] 'removeFirst(2)' 처음부터 제거 2는 인덱스가 아니며 몇개를 제거 할 것인지 물어보는 것입니다. 즉, 처음부터 제거할 것인데 2개를 제거하여라 라는 뜻입니다.
array1.removeLast() // [5, 6, 7, 8] 'removeLast()' 마지막 번째 값을 제거
array1.popLast() // [5, 6, 7] 'popLast()' 마지막 번째 값을 제거
array1.removeLast(2) // [5] 'removeLast()' 마지막 번째 부터 제거 하겠다 2개를
array1.removeAll() // [] 'removeAll()' 모두 제거하겠다.
// 2. 특정 범위 삭제하기
var array2 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
array2.removeSubrange(1...3) // [1, 5, 6, 7, 8, 9] '1...3'은 인덱스입니다. 인덱스 1부터 3에 해당하는 2,3,4 를 제거한 것 입니다.
array2[0..<2] = [] // [6, 7, 8, 9] 'array2'의 0부터 2미만, 0과 1인덱스가 가지고 있는 배열만큼을 빈배열로 넣겠다는 의미입니다. 0과 1이면 1,5 이죠.
[ 배열을 비교하는 방법 ]
// 배열 비교하기
var array1 = [1, 2, 3]
var array2 = [1, 2, 3]
var array3 = [1, 2, 3, 4, 5,]
array1 == array2 //true
array1.elementsEqual(array3) //false
[ 배열을 정렬하는 방법 ]
// 배열 정렬하기
let array1 = [1, 5, 3, 8, 6, 10, 14]
// 1. sort : 배열을 직접 "오름차순"으로 정렬
// sort는 배열 자체를 원본을 변경하는 개념입니다. 즉, 오름차 순으로 정렬이 되면서 배열 자체를 변경시킵니다.
array1.sort() // [1, 3, 5, 6, 8, 10, 14]
// 1-1. sort + 클로저 : 배열을 직접 "내림차순"으로 정렬
// sort 안에는 by라는 파라미터를 넣을 수 있습니다. 안 넣으면 디폴트가 오름차순이 됩니다.
// by에 부등호를 반대로 넣어주면 내림차순으로 정렬되며 내용 또한 변경이 됩니다.
array1.sort(by: >) // [14, 10, 8, 6, 5, 3, 1]
// 2. sorted : 원본은 그대로 두고, "오름차순"으로 정렬된 새로운 배열을 만들어 리턴
// 원본을 그대로 둔다는것이 포인트입니다.
let sortedArray = array1.sorted() // [1, 3, 5, 6, 8, 10, 14]
// 2-1. sorted + 클로저 : 원본은 그대로 두고, "내림차순"으로 정렬된 새로운 배열을 만들어 리턴
let sortedArray2 = array1.sorted(by: >) // [14, 10, 8, 6, 5, 3, 1]
세트(Set)
Set는 집합과 비슷
Set는 순서를 정의하지 않고 동일한 타입의 값을 저장
항목의 순서가 중요하지 않거나 항목이 한 번만 표시되도록 해야 하는 경우 배열 대신 집합을 사용 가능
세트 안에 있는 모든 값은 고유(unique)해야하므로 중복을 허용하지 않음
// Set 활용예시
var A = Set<String>() // A라는 변수에 문자열이 들어가는 Set 집합 자료구조가 들어가있습니다.
// 값 넣기
A.insert("Music") // A에 insert 하면 'Music' 을 넣어줄 수가 있습니다.
// 초기화 (배열과동일)
A = []
var B: Set<String> = ["1", "2", "3"] // 1,2,3이 들어간 Set입니다.
// Set도 동일하게 'isEmpty'비었는지와 'count'사용이 가능합니다.
// contains를 사용이 가능한데 포함이 되어있는지 아닌지 'bool' 값으로 리턴을 해줍니다.
// randomElement의 경우 랜덤으로 배열에서 뽑아낸다는 의미
B.isEmpty // false
B.count // 3
B.contains("1") // true
B.randomElement() // 3 (다른 element가 나올 수 있음)
// 업데이트(update) - 삽입, 교체, 추가
// 배열에서 사용하는 append가 없음
var set1: Set<Int> = [1,1,2,2,3,3] // 중복을 허용 하지 않기 때문에 1,2,3만 저장된 형태가 됩니다.
set1.update(with: 1) // 1 -> 기존에 있던 요소이므로 값을 옵셔널 타입으로 리턴
set1.update(with: 7) // nil -> 기존에 없던 요소이므로 Set에 요소가 추가되고 nil 리턴, 7은 배열에 포함되어 있지 않아 7을 Set 1에 추가를 해줍니다.
set1.remove(1) // 1 -> 삭제된 요소를 리턴 remove(1) 이건 인덱스 아니고 값입니다. 1,2,3,7 들어있었는데 1 자체를 제거한 겁니다.
set1 // [2,3,7]
set1.remove(5) // nil -> 존재하지 않는 요소를 삭제했을 때 에러는 발생하지 않고 nil 리턴
// 전체요소 삭제
set1.removeAll() // 전체삭제
set1.removeAll(keepingCapacity: true) // 요소는 제거하지만 메모리는 제거하지 않는다는 옵션
// 집합의 종류와 개념
let oddDigits: Set = [1, 3, 5, 7, 9]
let evenDigits: Set = [0, 2, 4, 6, 8]
let singleDigitPrimeNumbers: Set = [2, 3, 5, 7]
// 합집합
oddDigits.union(evenDigits).sorted()
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
// 교집합: 겹치는것이 없어 빈배열
oddDigits.intersection(evenDigits).sorted()
// []
// 차집합: 1과 9
oddDigits.subtracting(singleDigitPrimeNumbers).sorted()
// [1, 9]
// 대칭 차집합 : 1과 2와 9
oddDigits.symmetricDifference(singleDigitPrimeNumbers).sorted()
// [1, 2, 9]
// 이러한 집합의 종류와 개념은 잘 쓰이지 않습니다.
* 딕셔너리(Dictionary) *
'Dictionary'는 사전과 비슷
'Dictionary'는 순서를 정의하지 않고 같은 타입의 'key'와 같은 타입의 'value'를 저장
'key'는 중복 불가
모든 'key', 'value'는 같은 타입이어야 함
'key'와 'value'는 다른 타입이어도 가능
실물 사전을 찾는 것처럼 순서가 아닌 식별자 기준으로 값을 찾을 때 "Dictionary"를 사용
// 딕셔너리 알아보기
var A: [Int: String] = [:]
// [:]: 초기화 및 빈 딕셔너리 라는 뜻입니다.
// Int: Key
// String: value
/*
Key와 value라는 것은 말 그대로 Key는 우리가 찾고자 하는 열쇠이며
value를 찾고 싶은데 찾으려는 수단은 Key 입니다.
즉, 숫자로 접근해서 문자열을 얻고싶다는 의미가 되는 것을 알 수 있습니다.
*/
A[16] = "sixteen" // 16은 subscript가 아니라 "키"임
/*
이건 16번째 인덱스에 이 값을 넣는 것이 아닌 딕셔너리의 Key는 16이며
value는 "sixteen" 이라는 쌍을 [:] 딕셔너리에 저장을 해주는 것입니다.
*/
// 초기화
A = [:]
var B: [String: String] = ["YYZ": "값1", "DUB": "값2"]
// 'Key'도 'String' (문자열)
// 'value'도 'String' (문자열)
// 'YYZ', 'DUB'가 'Key' 입니다.
// "값1", "값2"가 'value' 입니다.
// 위 키워드로 접근 하여 value를 얻고자하는 것 입니다.
// key만 알고 싶을때도 있으며 value만 알고 싶을 때가 있는데 아래와 같이 keys와 values를 활용하여 알아낼 수 있습니다.
B.keys // ["YYZ", "DUB"] // key만 알고 싶을 때 사용
B.values // ["값1", "값2"] // value만 알고 싶을 때 사용
//keys와 values는 배열형태이기에 sorted함수를 적용할 수 있습니다.
B.keys.sorted() // ["DUB", "YYZ"] // sorted로 정렬을 하면 문자열로 오름차순이 정렬이 된 것을 알 수 있습니다.
B.values.sorted() // ["값2", "값1"]
B["AP"] = "값3" // AP라는 키를 추가합니다.
// B = ["YYZ": "값1", "DUB": "값2", "AP": "값3"]
// key에 매칭된 value 값 초기화
B["AP"] = nil // AP라는 추가된 키에 값3이 사라지고 nil이 대입되어버려서 기존처럼 YYZ와 DUB 두개의 형태가 됩니다.
// 딕셔너리 A 있는 값의 수
// B.count를 하면 key, value를 따로세지 않고 key, value를 한쌍으로 묶어 계산합니다.
print(B.count)
// 출력값: 2
// 딕셔너리 B에 있는 모든 key들
print(B.keys)
// ["YYZ", "DUB"]
// 업데이트 value에 대하여..
// 해당 key가 있다면 value를 덮어쓰고, 덮어쓰기 전 기존값울 반환
/*
forKey: "YYZ" YYZ가 이미 있는데 이것을 "Hi YYZ"로 바꿔 주려는 것입니다.
원래는 "값1"이 들어 있는데 바꿔 주려는 것 입니다. "Hi YYZ"가 들어가고 newYyz에는
기존에 있던 "값1" 이 newYyz에 리턴됩니다.
*/
let newYyz = B.updateValue("Hi YYZ", forKey: "YYZ") //
print(newYyz) // 출력값: Optional("값1")
/*
여기서 왜 옵셔널이냐하면 'key'를 적어줄 때
'key'가 실제로 들어있지 않을 수도 있기 때문에
들어 있지 않는다면 당연히 값을 줄 수 없으니 'nil'을 줘야하고
'nil'을 주기 위해서는 그것을 포함할 수 있는 'Optional'로 묶어 주어야 합니다.
그렇기 때문에 'key'가 만약 존재를 한다면 'Optional' 뒤에 값이 들어 있는 형태입니다.
'key'가 없다면 'nil'이 들어가게 되는 것입니다.
*/
// 값을 세팅을 해주었으니 다시 B에 YYZ에 접근해서 value를 출력을 해주면 Optional("Hi YYZ")로 나오게 됩니다.
print(B["YYZ"]) // 출력값: Optional("Hi YYZ")
// 해당 key가 없다면 그 key에 해당하는 'value'에 값을 추가하고 'nil'을 반환
let newAp = B.updateValue("Hello AP", forKey: "AP")
print(newAp) // 출력값: nil
print(B["AP"]) // 출력값: Optional("Hello AP")
728x90
'IOS > Swift-Study' 카테고리의 다른 글
[Swift-Study] 기초 문법종합반 1주차 3일차 정리 - 클래스, 구조체, 열거형 (0) | 2024.03.12 |
---|---|
[Swift-Study] 기초 문법종합반 1주차 3일차 정리 - 객체 지향 (0) | 2024.03.12 |
[Swift-Study] 기초 문법종합반 1주차 2일차 정리 - 스택, 큐 (0) | 2024.03.12 |
[Swift-Study] 기초 문법종합반 1주차 2일차 정리 - 옵셔널 (0) | 2024.03.12 |
[Swift-Study] 기초 문법종합반 1주차 1일차 정리 - 연산자, 조건문과 반복문 (2) | 2024.03.11 |