DEV_Larva
배열(2) 본문
앞서 배워본 배열의 생성 방법, 배열에 할당되어있는 값의 수정, 배열을 이용한 다양한 기능을 알아보았다.
지난 시간에 이어 남은 부분을 한번 학습 해보겠습니다!
🧑💻이번 Swift 시간에 배워볼 것은 다음과 같다. 👨🏻💻
- 배열의 데이터를 저장하고 찾는 방법
- 더욱 빠르게 데이터를 찾는 방법
- 열거형을 사용하는 방법
1. 배열의 데이터를 저장 하고 찾는 방법
var employee = ["Taylor Swift", "Singer", "Nashville"]
print("Name: \(employee[0])")
print("Job title: \(employee[1])")
print("Location: \(employee[2])")
위의 예제를 실행해본다면 결과는 어떻게 나올까? 물론 배열에 할당되어있는 요소의 값을 직접 Name, Job title, Location에 할당해주었기 때문에 순서대로 출력될 것이다.
이번에는 이렇게 해보자. print문 중간에 앞서 배운 배열의 기능 중 remove(at:1)을 이용하여 해당 요소를 삭제를 한 이후 출력을 해보면 어떻게 될까?
print("Name: \(employee[0])")
employee.remove(at: 1)
print("Job title: \(employee[1])")
print("Location: \(employee[2])")
위 예제를 실행해본다면 물론 오류가 발생한다. 물론이다. 해당 요소를 삭제하였고 그것을 출력을 하려니 당연히 출력이 안되는 것인데,
이 처럼 배열에서는 employee [2]가 그 위치인지 확신할 수 없다.
또한 배열을 변수로 선언하였기 때문에 employee [2]가 반드시 존재할 거라는 보장도 없다.
따라서 이와 같은 문제에서 벗어나기 위해서 Swift에서는 dictionaries라는 해결책을 제공해준다. dictionaries는 배열이 저장하는 것처럼 항목의 위치에 따라 저장하지는 않지만 항목을 저장할 위치를 결정할 수는 있다. 예시를 보자
let employee2 = [
"name": "Taylor Swift",
"job": "Singer",
"location": "Nashville"
]
print(employee2["name"])
print(employee2["job"])
print(employee2["location"])
해당 예제를 실행해보면 출력이 되긴 한다. 하지만 경고문과 함께 Optional이라는 문구가 결과 값 앞에 함께 출력되는 것을 확인할 수 있다.

모두 유효한 Swift코드이지만 값이 붙어 있지 않은 사전 키를 읽으려고 한다. 이러한 출력은 된 것도 아닌 아닌 것도 아닌 매우 눈에 거슬리는 결과이다. 🤔
dictionaries 내부 데이터에 접근할 때 값을 돌려받을 수 있는데 아무것도 돌려받지 못할 수도 있다. 이게 무슨 말인고하니
Swift는 데이터의 존재 여부가 선택 사항이어서 이러한 옵션을 호출한다. 그러니깐 데이터가 있을 수도 있고 없을 수도 있다.

위의 경고문을 자세히 보면 “Expression implicitly coerced from 'String?' to 'Any’”라고 한다. 'String'에서 'Any'로 암시적으로 강제됨"라고 하는데 이게 무슨 말인지 찾아보니 이는 이 데이터가 실제로 존재하지 않을 수 있기 때문에 출력을 할 거냐 말 거냐를 질문하는 것이다.
이를 위한 다른 Swift의 다른 대안을 알아보자!
dictionaries에서 값이 없는 경우를 대비해서 기본값을 미리 제공해보는 것이다. 예시를 보자
print(employee2["name", default: "Unknown"])
print(employee2["job", default: "Unknown"])
print(employee2["location", default: "Unknown"])

이번에는 저장하려는 명시적 유형을 사용해서 빈 dictionaries을 만든 이후 값을 하나씩 할당할 수 있다.
(1) [String: Int]()
var heights = [String: Int]()
heights["Yao Ming"] = 229
heights["Shaquille O'Neal"] = 216
heights["LeBron James"] = 206
이 예제가 의미하는 바는 무엇일까? 이는 키에는 문자열이, 값에는 정수가 있는 dictionaries을 의미한다. 각 dictionaries의 항목은 특정 키에 존재해야 한다. 따라서 중복 키가 존재할 수 없다. 대신, 이미 존재하는 키에 대한 값을 설정하면 Swift가 이전 값을 덮어쓴다.
(2) [String: String]()
var archEnemies = [String: String]()
archEnemies["Batman"] = "The Joker"
archEnemies["Superman"] = "Lex Luthor"
위에서 본 [String: Int]() 것과 같이 [String: String]()는 키와 값 둘 다 문자열이 있는 dictionaries을 의미한다.
dictionaries는 앞서 배운 배열의 기능이었던 count 나 removeAll() 모두 사용 가능하다. 배열과 동일하게 작동한다.
2. 더욱 빠르게 데이터를 찾는 방법
지금까지 Swift에서 데이터를 수집하는 두 가지 방법으로 배열과 dictionaries를 배웠다. 이번에는 Set에 대해서 배워보자.
이제 세트에 대한 예시를 통해 세트를 만들어 보자. 첫 번째 people의 경우 Set를 만든 예시이고 두 번째 people2의 경우 일반적인 배열이다.
let people = Set(["Denzel Washington", "Tom Cruise", "Nicolas Cage", "Samuel L Jackson"])
let people2 = ["Denzel Washington", "Tom Cruise", "Nicolas Cage", "Samuel L Jackson","Nicolas Cage"]
배열과 생긴 것은 매우 비슷하다. 배열 앞에 Set를 넣어주는 것 말고는 다른 것이 없다. 여기서 Set는 무슨 역할을 할까?? 위 예시를 출력해보면 대략 알 수 있다.

결과를 보자 첫 번째 줄은 위에서 세트를 이용하여 출력한 것이고 두 번째는 일반 배열이다. 세트를 이용한 경우 배열에서 중복되는 값을 자동으로 제거하고 배열에서 사용된 정확한 순서를 기억하지 않고 그냥 출력한다는 것이다.
따라서 Set는 항목이 어떤 순서로 오는지 상관하지 않는다는 것이다. 그래서 앞서 배운 insert, append 또한 의미가 없습니다. 이전에는 배열의 끝 부분에 추가하는 방식이었지만 Set에서는 항목의 끝이라는 것이 매번 바뀌기 때문이다.
그럼 세트는 왜 사용하는 걸까?
1.
중복 데이터를 저장하지 않는 것이 때로는 정확히 원하는 것이다. 앞의 예에서 배우를 선택한 이유가 있다. 많은 영화를 보고 나면
한 가지 의문점이 든다. 왜 영화배우들의 이름은 서로 겹치지 않을까?
이름은 같을 수 있지만 성까지는 다른 것을 볼 수 있는데 이는 예명을 만들 때 스크린 배우 길드는 혼란을 피하기 위해 모든 구성원들이 독특한 예명을 가져야 한다고 요구하기 때문이라고 한다.
이것이 결국 중복이 절대 허용되지 않는다는 것을 의미한다.
따라서 위 영화배우들의 이름으로 예시를 만들어 보았으며 이를 통해 세트가 어느 경우에서 필요한지도 간단하게 알아볼 수 있었다.
2.
지정한 순서에 따라 항목을 저장하는 대신 매우 최적화된 순서로 항목을 빠르게 찾을 수 있도록 항목을 저장한다. 1000개의 영화 이름이 배열되어 있고 "다크 나이트"가 포함되어 있는지 확인하기 위해 contains()와 같은 것을 사용하는 경우 Swift는 일치하는 항목을 찾을 때까지 모든 항목을 검사해야 한다. 다크 나이트가 배열에 없기 때문에 1000개의 영화 이름을 모두 검사해야 한다.
이에 비해, Set는 백만 개의 아이템이 있다 하더라도, 심지어 천만 개의 아이템이 있다 하더라도, 배열은 동일한 작업을 수행하는 데 몇 분 또는 그 이상이 걸릴 수 있습니다.
대부분의 경우 Set가 아닌 배열을 사용하지만, 때로는 특정 문제를 해결하기 위해 Set가 올바른 선택이라는 것을 알게 되고, 그렇지 않으면 느린 코드가 순식간에 실행되게 될 수도 있다는 것이다.
3. 열거형(enum) 사용하기
열거형이란 Enumeration의 약어로 같은 주제로 연관된 데이터들을 멤버로 구성하여 나타내는 자료형을 의미한다.
바로 요일을 이용하여 enum을 사용해보자
enum Weekday {
case monday
case tuesday
case wednesday
case thursday
case friday
}

day라는 변수를 이용하여 위에서 만든 enum의 요일들을 출력해보았다. 정상적으로 출력되는 것을 볼 수 있다.
만약 열거형 내부에 선언하지 않은 요일이나, 다른 것을 출력해보려고 한다면 어떻게 될까?

요일이 아닌 달을 출력해보고자 하였는데 다음과 같은 오류가 출력된다. 말 그대로 Weekday의 멤버에 January가 없다고 출력된다.
Weekday의 case에 January을 만들어 주지 않았기 때문이다.
그렇다면 이번에는 열거형을 조금 더 쉽게 이용해 보는 방법을 알아보자!
1.
enum Weekday {
case monday, tuesday, wednesday, thursday, friday
}
위에서 선언하였던 Weekday의 경우 case를 모든 요일마다 함께 사용하였지만 열거형은 case를 한 번만 사용하고 쉼표를 이용하여 구분할 수 있다.
2.
var day = Weekday.monday
day = .tuesday
day = .friday
변수나 상수에 값을 할당하면 데이터 유형이 고정된다는 점을 기억해야 한다. 처음에는 변수를 문자열로 설정하고 나중에는 정수로 설정할 수 없다. 열거형의 경우 다음과 같이 첫 번째 변수를 할당 후에 열거형 이름을 건너뛸 수 있다.
이번 시간에는 배열 생성과 배열 내부 데이터에 접근 하는 방법, enum을 간략하게 배워보았다. 다음 시간에도 아마 복잡한 데이터 유형에 대해서 계속 해서 배울것 같다. 일단은 오늘은 여기서 마무리!😋
learning by repetition
'iOS > Swift 문법' 카테고리의 다른 글
조건문 & 삼항 연산자 (0) | 2022.07.14 |
---|---|
Type annotations(타입 추론) (0) | 2022.07.12 |
배열 (0) | 2022.07.06 |
Bool & 문자열 보간법 (0) | 2022.07.05 |
변수와 상수(2) (0) | 2022.07.01 |