[iOS/Swift/Basic] 컬렉션형(Array, Dictionary, Set)
📌 이번 글은
Swift의 컬렉션 타입 Array, Dictionary, Set에 대한 설명입니다.
Array (배열)
같은 타입의 데이터를 일렬로 나열한 후 순서대로 저장하는 형태의 컬렉션 타입
Array의 기본 기능
.count
배열의 요소 개수 반환
var names: Array<String> = ["suni", "zico", "mino"]
print(names.count) // 3
.isEmpty
빈 배열 인지 반환
var emptyArray: [Any] = [Any]()
print(emptyArray.isEmpty) // true
.first
배열의 맨 처음 요소 반환
.last
배열의 맨 마지막 요소 반환
var names: Array<String> = ["suni", "zico", "mino", "zico"]
print(names.first ?? "first nil") // suni
print(names.last ?? "last nil") // zico
.firstIndex(of:)
해당 요소의 인덱스 반환 (해당 요소가 없다면 nil 반환)
만약 중복된 요소가 있다면 제일 먼저 발견된 인덱스 반환
var names: Array<String> = ["suni", "zico", "mino", "zico"]
print(names.firstIndex(of: "zico") ?? "index nil") // 1
print(names.firstIndex(of: "pio") ?? "index nil") // index nil
.append(_: )
배열의 맨 뒤에 요소 추가
var names: Array<String> = ["suni", "zico", "mino"]
names.append("alice") // 마지막에 alice 추가
print(names) // ["suni", "zico", "mino", "alice"]
names.append(contentsOf: ["pio", "junny"]) // 맨 마지막에 pio, junny 추가
print(names) // ["suni", "zico", "mino", "alice", "pio", "junny"]
.insert(_: at: )
배열 중간에 요소 삽입
var names: Array<String> = ["suni", "zico", "mino"]
names.insert("alice", at: 2) // 인덱스 2에 삽입
print(names) // ["suni", "zico", "alice", "mino"]
names.insert(contentsOf: ["pio", "junny"], at: 1) // 인덱스 1의 위치에 pio, junny 삽입
print(names) // ["suni", "pio", "junny", "zico", "alice", "mino"]
.removeFirst()
배열의 첫 번째 요소 삭제 후 삭제된 요소 반환
.removeLast()
배열의 마지막 요소 삭제 후 삭제된 요소 반환
.remove(at:)
배열의 해당 인덱스 요소 삭제 후 삭제된 요소 반환
var names: Array<String> = ["suni", "zico", "mino", "alice", "pio", "junny"]
print(names.removeFirst()) // 첫번째 요소 제거 후 제거된 요소 반환 : suni
print(names) // ["zico", "mino", "alice", "pio", "junny"]
print(names.removeLast()) // 마지막 요소 제거 후 제거된 요소 반환 : junny
print(names) // ["zico", "mino", "alice", "pio"]
print(names.remove(at: 0)) // 인덱스 0번째 요소 제거 후 제거된 요소 반환 : zico
print(names) // ["mino", "alice", "pio"]
Dictionary (딕셔너리)
요소들이 순서 없이 키와 값의 쌍으로 구성되는 컬렉션 타입
- 키(key) : 값 value 을 대변하는 유일한 식별자. 하나의 딕셔너리 안의 같은 이름을 중복해서 사용할 수 없다.
Dictionary의 기본 기능
딕셔너리 생성
// 키 - String / 값 - Int
var ageForName1: Dictionary<String, Int> = Dictionary<String, Int>()
var ageForName2: [String: Int] = [String: Int]()
var ageForName3: [String: Int] = [:]
var ageForName4: [String: Int] = ["suni": 25, "zico": 28, "mino": 27]
// typealias를 사용하여 생성
typealias StringIntDictionary = [String: Int]
var ageForName5: StringIntDictionary = StringIntDictionary()
딕셔너리 값 반환
- dictionary["key명", default:] 키에 해당하는 값이 없으면 기본값(default)을 반환
var ageForName: [String: Int] = ["suni": 25, "zico": 28, "mino": 27]
// 키에 해당하는 값 반환
print(ageForName["suni"] ?? "suni is nil") // 25
// 키에 해당하는 값이 없으면 기본값을 반환하도록 할 수 있다.
print(ageForName["pio", default: 0]) // 0
딕셔너리 값 수정
var ageForName: [String: Int] = ["suni": 25, "zico": 28, "mino": 27]
// 값 수정
ageForName["zico"] = 30
print(ageForName["zico", default: 0]) // 30
딕셔너리 값 추가
var ageForName: [String: Int] = ["suni": 25, "zico": 28, "mino": 27]
// 키:값 추가
ageForName["somin"] = 35 // somin라는 키로 35라는 값을 추가
print(ageForName["somin", default: 0]) // 35
.count
딕셔너리 요소 개수 반환
.isEmpty
빈 딕셔너리인지 반환
var ageForName: [String: Int] = ["suni": 25, "zico": 28, "mino": 27]
print(ageForName.isEmpty) // false
print(ageForName.count) // 3
.removeValue(forKey:)
키에 해당하는 값 제거 후 제거된 값 반환
// 키에 해당하는 값을 제거 후 제거된 값 반환
print(ageForName.removeValue(forKey: "suni") ?? "suni is nil") // 25
// 위에서 해당 값이 이미 제거되었으므로 nil 반환
print(ageForName.removeValue(forKey: "suni") ?? "suni is nil") // suni is nil
Set (세트)
- 같은 타입의 데이터를 순서 없이 하나의 묵음으로 저장하는 형태의 컬렉션 타입
- 중복된 값이 존재하지 않는다.
- 순서가 중요하지 않거나 각 요소가 유일한 값이어야 하는 경우에 사용
- 세트의 요소로는 해시 가능한 값이 들어와야 한다.
Set의 기본 기능
.insert(_: )
세트에 요소를 추가
.remove(_: )
요소를 삭제
해당 요소가 삭제된 후 반환
var names1: Set<String> = Set<String>() // 빈 세트 생성
var names2: Set<String> = [] // 빈 세트 생성
// Array와 마찬가지로 대괄호 사용
var names: Set<String> = ["suni", "zico", "mino", "suni"]
// 그렇기 때문에 타입 추론을 사용하게 되면 컴파일러는 Array로 타입을 지정합니다.
var numbers = [100, 200, 300]
print(type(of: numbers)) // Array<Int>
print(names.isEmpty) // false
print(names.count) // 3 - 중복된 값은 허용되지 않아 suni는 1 개만 남음
names.insert("somin")
print(names.count) // 4
print(names.remove("zico")) // zico
print(names.remove("pio")) // nil
집합관계를 표현하고자 할 때 유용
.intersection(_: ) 교집합
.symmetricDifference(_: ) 여집합
.union(_: ) 합집합
.subtracting(_: ) 차집합
.sorted() : 정렬된 배열 반환
let aStudents: Set<String> = ["suni", "zico", "mino"]
let bStudents: Set<String> = ["suni", "pio", "june", "zico", "somin"]
// 교집합 ["suni", "zico"]
let intersectSet: Set<String> = aStudents.intersection(bStudents)
print(intersectSet)
// 여집합의 합(배타적 논리합) ["june", "mino", "pio", "somin"]
let symmetricDiffSet: Set<String> = aStudents.symmetricDifference(bStudents)
print(symmetricDiffSet)
// 차집합 ["mino"]
let subtractSet: Set<String> = aStudents.subtracting(bStudents)
print(subtractSet)
// 합집합 ["somin", "zico", "suni", "mino", "june", "pio"]
let unionSet: Set<String> = aStudents.union(bStudents)
print(unionSet)
print(unionSet.sorted()) // ["june", "mino", "pio", "somin", "suni", "zico"]
두 세트의 포함관계 연산(교집합, 합집합 등)하기에 매우 용이
.isDisjoint(wint:) 두 집합의 교집합이 없을 때 true
.isSubset(of:) 부분 집합 여부
.isSuperset(of:) 전체 집합 여부 (A.isSuperSet(of: B) - A가 B의 상위 집합 인지?)
컬렉션형의 Random/Shuffle 함수
.randomElement()
임의의 요소 추출하여 반환
.shuffle()
요소를 임의로 뒤섞음
.shuffled()
자신의 요소는 그대로 둔 채 새로운 컬렉션에 임의의 순서로 섞어서 반환
var array: [Int] = [0, 1, 2, 3, 4]
var set: Set<Int> = [0, 1, 2, 3, 4]
var dictionary: [String: Int] = ["a": 1, "b": 2, "c": 3]
var string: String = "string"
print(array.randomElement()) // 임의의 요소 - Optional(3)
print(array.shuffled()) // [0, 4, 2, 1, 3] : 뒤죽박죽된 배열
print(array) // [0, 1, 2, 3, 4] : array 내부는 그대로
array.shuffle() // array 자체를 뒤죽박죽으로 뒤섞기
print(array) // [0, 4, 3, 2, 1]
print(set.shuffled()) // [3, 4, 2, 1, 0] : 세트를 뒤섞으면 배열로 반환
//set.shuffle() // ERROR: 세트는 순서가 없기 때문에 스스로 뒤섞일 수 없다.
print(dictionary.shuffled()) // [(key: "b", value: 2), (key: "c", value: 3), (key: "a", value: 1)] : 딕셔너리는 뒤섞이면 (키, 값)이 쌍을 이룬 튜플의 배열을 반환
print(string.shuffled()) // ["s", "g", "i", "r", "n", "t"] : String도 컬렉션!
🙋🏻♀️ 참고
야곰, ⌜스위프트 프로그래밍: Swift5⌟, 한빛미디어(2019)