Swift문법 - (9)컬렉션(Collection)

Youth·2022년 9월 21일
0

swift문법공부

목록 보기
9/27
post-thumbnail

스위프트의 컬렉션(Collection) - 데이터바구니

  1. Array(배열) - 데이터를 순서대로 저장하는 컬렉션, 순서O
  2. Dictionary(딕셔너리) - 데이터를 키와 값으로 하나의 쌍으로 만들어관리, 순서X
  3. Set(집합) - 수학에서의 집합과 비슷한 연산을 제공, 순서X

배열(Array)

  • 데이터를 순서대로 저장하는 컬렉션 (자동으로 순번 지정됨)
  • 배열의 문법 약속
    • [] 대괄호로 묶는다. 배열의 인덱스의 시작은 0부터 (모든 프로그래밍 언어 공통 사항)
    • 1개의 배열에는 동일한 타입의 데이터만 담을 수 있다.
    • (순서가 있기 때문에) 값은 중복 가능
// 배열 리터럴로 배열을 생성해서 저장
var numsArray = [1, 2, 3, 4, 5]   
let numsArray1 = [20, 2, 7, 4, 5, 7]
var stringArray = ["Apple", "Swift", "iOS", "Hello"]

// 배열을 생성하는 방법
let emptyArray1: [Int] = []    // 내가 가장 많이 쓰는 방법
let emptyArray2 = Array<Int>()
let emptyArray3 = [Int]()

배열의 기본 기능

var numsArray = [1, 2, 3, 4, 5]   

numsArray.count            // 요소의 갯수
numsArray.isEmpty          // 비어있는지 -> Bool
numsArray.contains(1)      // 파라미터로 값을 전달 -> Bool
numsArray.contains(8)   
numsArray.randomElement()  // 하나의 요소를 랜덤으로 뽑는다
numsArray.swapAt(0, 1)     // 0번째 요소를 1번째 요소와 바꾼다

배열의 각 요소(element)에 대한 접근

numsArray = [1, 2, 3, 4, 5]   // 배열 리터럴
stringArray = ["Apple", "Swift", "iOS", "Hello"]

// 리턴값 String?  ====> 빈 배열이라면 nil 리턴 ====> 옵셔널
stringArray.first
stringArray.last

stringArray.startIndex    // 0
stringArray.endIndex      // 4

**endIndex를 통해서 배열의 마지막 요소를 가지고 오고 싶으면 -1**
stringArray[stringArray.endIndex - 1]
stringArray[stringArray.index(before: stringArray.endIndex)]

// 0번째 인덱스에서 2칸 띄워져있는 인덱스는?
stringArray.index(0, offsetBy: 2)

// 앞에서 부터 찾았을때 첫 "iOS"는 배열의 (앞에서부터) 몇번째 = 2
stringArray.firstIndex(of: "iOS")    

// 뒤에서 부터 찾았을때 첫 "iOS"는 배열의 (앞에서부터) 몇번째 = 2
stringArray.lastIndex(of: "iOS")     

// .firstIndex(of:)는 optional type 왜냐? 없을수도 있으니까
if let index = stringArray.firstIndex(of: "iOS") {
    print(index)   // result : 2
}

삽입하기(insert)

var alphabet = ["A", "B", "C", "D", "E", "F", "G"]

// 앞 또는 중간에 삽입하기

alphabet.insert("c", at: 4)
// result : ["A", "B", "C", "D", "c", "E", "F", "G"]

alphabet.insert("c", at: alphabet.endIndex)
// result : ["A", "B", "C", "D", "c", "E", "F", "G", "c"]

alphabet.insert(contentsOf: ["a","b","c"], at: 0)
// result : ["a", "b", "c", "A", "B", "C", "D", "c", "E", "F", "G", "c"]

alphabet.insert(contentsOf: ["a","b","c"], at: alphabet.endIndex)
// result : ["a", "b", "c", "A", "B", "C", "D", "c", "E", "F", "G", "c", "a", "b", "c"]

교체하기(replace)

alphabet = ["A", "B", "C", "D", "E", "F", "G"]

// 요소 교체하기
alphabet[0] = "a"

// 범위를 교체하기
alphabet[0...2] = ["x", "y", "z"]

// 원하는 범위 삭제
alphabet[0...1] = []

// 교체하기 함수 문법
alphabet.replaceSubrange(0...2, with: ["a", "b", "c"])

추가하기(append)

alphabet = ["A", "B", "C", "D", "E", "F", "G"]
alphabet += ["H"]

// 추가하기 함수 문법
**// element를 추가하는것과 collection을 추가하는게 따로 있음**
alphabet.append("H")   // 맨 마지막에 추가하는 것
alphabet.append(contentsOf: ["H", "I"])

삭제(제거)하기(remove)

alphabet = ["A", "B", "C", "D", "E", "F", "G"]

// 서브스크립트 문법으로 삭제
alphabet[0...2] = []   //빈배열 전달하면 해당 범위가 삭제

// 요소 한개 삭제
alphabet.remove(at: 2)  // 삭제하고, 삭제된 요소 리턴

// 요소 범위 삭제
alphabet.removeSubrange(0...2)

alphabet = ["A", "B", "C", "D", "E", "F", "G"]

// 맨 앞에 요소 삭제하고 삭제된 요소 리턴 (리턴형 String)
alphabet.removeFirst()
 // 앞의 두개의 요소 삭제 ===> 리턴은 안함
alphabet.removeFirst(2)

// 맨 뒤에 요소 삭제하고 삭제된 요소 리턴 (리턴형 String)
alphabet.removeLast()   
alphabet.removeLast(2)

// 배열의 요소 모두 삭제(제거)
alphabet.removeAll()

배열의 기타 기능

var nums = [1, 2, 3, 1, 4, 5, 2, 6, 7, 5, 0]

// 배열을 정리해보기
// 1) 배열을 직접정렬하는 메서드  sort  (동사)
// 2) 정렬된 새로운 배열을 리턴  sorted (동사ing/동사ed)

nums.sort()      // 배열을 직접 정렬 (오름차순) (배열자체가 변함)
nums.sorted()    // 배열자체가 변하지 않음 = 변수에 할당

nums.reverse()   // 요소를 역순으로 정렬  (배열리턴 하지 않음)
nums.reversed()

배열의 비교

let a = ["A", "B", "C"]
let b = ["a", "b", "c"]

// 두 배열을 비교
a == b   // false
a != b   // true

// 개별요소 비교, 저장순서도 비교 하기 때문에

반복문과의 결합

nums = [10, 11, 12, 13, 14]

// (offset: 0, element: 10)
for tuple in nums.enumerated() {
    print(tuple)
    print("\(tuple.offset) - \(tuple.element)")
}

딕셔너리(Dictionary)

  • 딕셔너리의 문법 약속
    • [] 대괄호로 묶는다. (쌍을 콜론으로 처리)
    • 키값은 유일해야함 / 중복 불가능(구분하는 요소이기 때문에) 밸류값은 중복 가능
    • 1개의 딕셔너리에는 동일한 자료형 쌍의 데이터만 담을 수 있음
    • 키값은 Hashble 해야함 - 해쉬함수에서 input으로 쓰일수있는 타입이어야함
      • swift의 기본타입은 모두 Hashable하다(custom 타입은 불가)

Hashable(Key)

  • 내부적으로 구현되어있는 알고리즘(어떤알고리즘인지는 알 필요없음)
  • 해쉬함수를 거치면 고정된길이의 숫자 or 글자이면서 유일한 값이 나옴
  • 배열처럼 하나하나 비교할필요 없이 hash값으로 바로 요소를 찾을수있다(빠름)
// 딕셔너리 리터럴로 생성해서 저장
var dic = ["A": "Apple", "B": "Banana", "C": "City"]  
let dic1 = [1: "Apple", 2: "Banana", 3: "City"]

// 단축문법
var words: [String: String] = [:]

// 정식문법
let words1: Dictionary<Int, String>

// 빈 딕셔너리의 생성
let emptyDic1: Dictionary<Int, String> = [:]
let emptyDic2 = Dictionary<Int, String>()
let emptyDic3 = [Int: String]()

딕셔너리의 기본 기능

dic = ["A": "Apple", "B": "Banana", "C": "City"]
dic.count
dic.isEmpty

// contains 함수가 존재하긴 하나, 뒤에서 배울 클로저의 내용을 알아야함
dic.contains { (key, value) in
    key == "A" && value == "Banana"
}

dic.contains { $0.key == "A" }

// Named Tuple 형태로 리턴
if let tuple = dic.randomElement() {     
		// 각 요소가 tuple로 리턴 (key: "B", value: "Banana")
    print(tuple)
    print("\(tuple.key) 그리고 \(tuple.value)")
}

딕셔너리의 각 요소(element)에 대한 접근

  • 서브스크립트 문법으로 "키"를 전달
dic = ["A": "Apple", "B": "Banana", "C": "City"]

dic["A"]        // nil의 가능성 =====> String?(옵셔널)

if let a = dic["A"] {    // 옵셔널 바인딩
    print(a)
} else {
    print("Not found")
}

업데이트 (update) - 삽입하기 / 교체하기 / 추가하기

words = [:]

words["A"] = "Apple"   // 애플로 다시 바꾸기
words["B"] = "Banana"  // 동일한 키가 없으면 ===> 추가하기
words["B"] = "Blue"    // 동일한 키가 있으면 ===> 기존 밸류 덮어쓰기

words.updateValue("City", forKey: "C")

// (정식 기능) 함수 문법 (update + insert = upsert)
// 새로운 요소가 추가되면 ==> 리턴 nil
words.updateValue("City", forKey: "C")   

//words = [:]      // 빈 딕셔너리로 만들기
words = ["A": "A"]   // 전체 교체하기(바꾸기)
💡 딕셔너리는 append 함수를 제공하지 않음 - 순서가 없기때문에

딕셔너리 삭제하기

dic = ["A": "Apple", "B": "Banana", "C": "City"]
dic["B"] = nil    // 해당요소 삭제
//result : ["C": "City", "A": "Apple"]

dic.removeValue(forKey: "A")   // 삭제후, 삭제된 값 리턴
dic.removeValue(forKey: "A")   // 다시 삭제해보기 ===> nil리턴

dic.removeAll()

세트(집합)

  • Set의 문법 약속
    • 생김새는 배열과 같음(따라서, 생성시 타입을 선언 해야함)
    • 수학에서의 집합과 동일하기 때문에 요소는 유일해야함(순서가 존재하지 않음)
var set: Set = [1, 1, 2, 2, 3, 3, 3]

// 단축문법
let set1: Set = [1, 2, 3]

// 정식문법
let set2: Set<Int> = [1, 2, 3]

// 빈 세트의 생성
let emptySet: Set<Int> = []
let emptySet1 = Set<Int>()

Set의 기본기능

set.count
set.isEmpty

set.contains(1)
set.randomElement()

업데이트 (update) - 삽입하기 / 교체하기 / 추가하기

set.update(with: 1)     // Int?

set.update(with: 7)     // 새로운 요소가 추가되면 ====> 리턴 nil

삭제하기

var stringSet: Set<String> = ["Apple", "Banana", "City", "Swift"]

// 요소 삭제해 보기
stringSet.remove("Swift")     // "Swift" 삭제한 요소를 리턴
stringSet                     // ["Hello", "Apple"]

// 존재하지 않는 요소를 삭제해보기
stringSet.remove("Steve")       // nil    (에러는 발생하지 않음)

// 전체요소 삭제
stringSet.removeAll()
stringSet.removeAll(keepingCapacity: true)
💡 Set을 정렬하면, 배열로 리턴함 (정렬은 순서가 필요하기 때문)

Set의 활용(집합의 활용)

a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [1, 3, 5, 7, 9]     // 홀수 모음
c = [2, 4, 6, 8, 10]    // 짝수 모음
d = [1, 7, 5, 9, 3]     // 홀수 모음
  • 부분집합 / 상위집합 / 서로소
// 부분집합 여부를 판단

b.isSubset(of: a)   // true 부분집합 여부
b.isStrictSubset(of: a)   // false 진부분집합 여부

// 상위집합
a.isSuperset(of: b)    // true 상위집합 여부
a.isStrictSuperset(of: b)   // false  진상위집합 여부

// 서로소 여부
d.isDisjoint(with: c)
  • 합집합
var unionSet =  b.union(c)
//b.formUnion(c)      // 원본변경
  • 교집합
var interSet = a.intersection(b)
//a.formIntersection(b)      // 원본변경
  • 차집합
var subSet = a.subtracting(b)
//a.subtract(b)       // 원본변경
  • 대칭차집합
var symmetricSet = a.symmetricDifference(b)
//a.formSymmetricDifference(b)       // 원본변경
profile
AppleDeveloperAcademy@POSTECH 1기 수료, SOPT 32기 iOS파트 수료

1개의 댓글

comment-user-thumbnail
2024년 3월 16일

:0

답글 달기