[Swift] 3. 데이터 타입(2) - 배열, 튜플, 딕셔너리, 세트

Hoojeong Kim·2021년 9월 6일
0

Swift Base

목록 보기
5/22
post-thumbnail

데이터 타입 고급

기본적인 데이터 타입에 대해 알아봤으니, 더 복잡한 내용을 다뤄보고자 한다. 이제 프로젝트에서 유용하게 사용할 수 있는 튜플이나 컬렉션형 등의 확장된 내용에 대해 배워보자.

타입 추론

스위프트에서는 변수나 상수를 선언할 때 특정 타입을 명시하지 않아도 컴파일러가 할당된 값을 기준으로 변수나 상수의 타입을 결정한다.

var name = "Hoojeong"  //  타입을 지정하지 않았으나 타입 추론을 통해 String 타입으로 선언

name = 100  // String 변수로 지정되었기 때문에 정수를 할당하려고 하면 오류가 발생한다.

타입 별칭

스위프트에서 기본으로 제공하는 데이터 타입이든, 사용자가 임의로 만든 데이터 타입이든 이미 존재하는 데이터 타입에 임의로 다른 이름을 부여할 수 있다.

typealias MyInt = Int

let x : MyInt = 100

튜플(Tuple)

튜플은 타입의 이름이 따로 지정되어 있지 않은, 프로그래머 마음대로 만드는 타입이다. 스위프트의 튜플은 파이썬의 튜플과 유사하다.

튜플은 타입 이름이 따로 없으므로 일정 타입의 나열만으로 튜플 타입을 생성해줄 수 있다. 튜플에 포함될 데이터의 새구는 자유롭게 정할 수 있다.

// String, Int, Double 타입을 갖는 튜플
var Person : (String, Int, Double) = ("Hoojeong", 22, 160.0)

// 인덱스를 사용해 값을 출력할 수 있다.
print("이름 : \(Person.0), 나이 : \(Person.1), 키 : \(Person.2)")

// 인덱스를 사용해 값을 바꿀 수 있다.
Person.1 = 20
Person.2 = 165.0

print("이름 : \(Person.0), 나이 : \(Person.1), 키 : \(Person.2)")
이름 : Hoojeong, 나이 : 22, 키 : 160.0
이름 : Hoojeong, 나이 : 20, 키 : 165.0

튜플 요소의 이름이나 별칭을 정하는 것도 가능하다.

var Person : (name : String, age : Int, height : Double) = ("Hoojeong", 22, 160.0)

// 요소 이름을 통해 값을 출력할 수 있다.
print("이름 : \(Person.name), 나이 : \(Person.age), 키 : \(Person.height)")

// 요소 이름이나 인덱스를 통해 값을 바꿀 수 있다.
Person.age = 20
Person.2 = 165.0

print("이름 : \(Person.0), 나이 : \(Person.1), 키 : \(Person.2)")

print("\n")

// 튜플의 별칭을 정할수 있다.
typealias DogTuple = (name : String, age : Int, weight : Double)

let happy : DogTuple = ("happy", 2, 4.2)

print("이름 : \(happy.name), 나이 : \(happy.age), 무게 : \(happy.weight)")
이름 : Hoojeong, 나이 : 22, 키 : 160.0
이름 : Hoojeong, 나이 : 20, 키 : 165.0


이름 : happy, 나이 : 2, 무게 : 4.2

배열(Array)

배열은 같은 타입의 데이터를 일렬로 나열한 후 순서대로 저장하는 형태의 컬렉션 타입이다.

// 배열 선언하기
var names : Array<String> = ["abc", "def", "ghi"]

// Array<String>의 축약 표현
var names2 : [String] = ["abc", "def", "ghi"]

// 비어있는 배열 선언하기
var names3 : Array<String> = Array<String>()
var names4 : [String] = []
// Any 데이터를 요소로 하는 빈 배열 생성
var empty : [Any] = [Any]()
var empty : [Any] = Array<Any>()

// 배열의 타입을 명시했다면, []로 빈 배열 생성 가능
var emptyArray : [Any] = []

배열은 각 요소에 인덱스를 통해 접근할 수 있다. 인덱스는 0부터 시작하며, 잘못된 인덱스로 접근할 경우, Exception 오류가 발생한다.

var alphabet = ["A", "B", "C", "D"]

print(alphabet.count)  // 배열의 요소 개수
print(alphabet[1])

alphabet[1] = "H"

print(alphabet[1])
print(alphabet[4])  // 배열의 범위를 벗어났기 때문에 오류 발생

print(alphabet)
4
B
H
["A", "H", "C", "D"]

배열의 맨 뒤에 요소를 추가하고 싶다면 append(_:) 메서드를 사용한다. 중간에 요소를 추가하고 싶다면 insert(_:at:) 메서드를 사용한다.

// 배열에 요소 추가
alphatbet[4] = "E"  // 범위를 벗어났기 때문에 오류 발생
alphabet.append("E")   // 배열의 맨 뒤에 요소 추가
print(alphabet)

alphabet.append(contentsOf : ["F", "G"]) // 한 번에 여러 개 추가
print(alphabet)

alphabet.insert("B", at : 1)  // 인덱스 1에 B 추가
print(alphabet)

alphabet.insert(contentsOf : ["X", "Y"], at : 3)  // 인덱스 3에 한 번에 여러 개 추기
print(alphabet)
["A", "H", "C", "D", "E"]
["A", "H", "C", "D", "E", "F", "G"]
["A", "B", "H", "C", "D", "E", "F", "G"]
["A", "B", "H", "X", "Y", "C", "D", "E", "F", "G"]

맨 처음과 마지막 요소는 first, last 프로퍼티를 통해 가져올 수 있으며, firstIndex(of:) 메서드를 사용해 해당 요소의 인덱스를 알아낼 수 있다.

만약 중복된 요소가 있다면, 제일 먼저 발견된 요소의 인덱스를 반환한다.

// 특정 요소의 인덱스 알아내기
print(alphabet.firstIndex(of : "H"))
print(alphabet.firstIndex(of : "K"))

// 맨 처음과 맨 마지막 요소 알아내기
print(alphabet.first)
print(alphabet.last)
Optional(2)
nil
Optional("A")
Optional("G")

만약 요소를 삭제하고 싶다면 remove(_:) 메서드를 사용하는데, 메서드를 사용하면 해당 요소가 삭제된 후 반환된다.

// 특정 요소 삭제하기
let firstItem : String = alphabet.removeFirst()  // 첫 번째 요소 삭제
let lastItem : String = alphabet.removeLast()  // 마지막 요소 삭제
let indexOneItem : String = alphabet.remove(at: 1)  // 인덱스 1 요소 삭제

print(firstItem)
print(lastItem)
print(indexOneItem)
print(alphabet)
A
G
H
["B", "X", "Y", "C", "D", "E", "F"]

특정 인덱스 범위의 요소들만 출력하는 것도 가능하다.

// 요소 출력하기
print(alphabet)  // 전체 요소 출력하기
print(alphabet[2 ... 4])// 인덱스가 2 ~ 4에 해당하는 요소 출력하기
["B", "X", "Y", "C", "D", "E", "F"]
["Y", "C", "D"]

딕셔너리

딕셔너리는 요소들이 순서 없이 키와 값의 쌍으로 구성되는 컬렉션 타입이다. 딕셔너리에 저장되는 값은 항상 키와 쌍을 이루게 되는데, 딕셔너리 안에는 키가 하나이거나 여러 개일 수 있다.

이때 하나의 키는 값을 대변하는 유일한 식별자로서 같은 이름을 중복해서 사용할 수 없다.

// 딕셔너리 선언하기
var dictionary : Dictionary<String, Int> = Dictionary<String, Int>()
var dictionary : [String: Int] = [String : Int]()
var dictionary : StringIntDictionary = StringIntDictionary()

// 딕셔너리 축약 표현
var dict : [String: Int] = [:]

딕셔너리는 다음과 같이 사용할 수 있다.

var numberForName: [String: Int] = ["Kim": 100, "Lee": 200, "Choi": 300]

print(numberForName.isEmpty)   // 딕셔너리가 비어있는지 확인
print(numberForName.count)     // 딕셔너리의 개수 확인

// 키로 값 출력하기
print(numberForName["Kim"])
print(numberForName["Park"])   // 해당되는 키가 없으므로 nil 출력

// 값 추가하기
numberForName["Koh"] = 400
print(numberForName)

// 특정 키로 값 지우기
numberForName.removeValue(forKey: "Kim")
print(numberForName)
false
3
Optional(100)
nil
["Kim": 100, "Lee": 200, "Koh": 400, "Choi": 300]
["Lee": 200, "Koh": 400, "Choi": 300]

세트

세트는 같은 타입의 데이터를 순서 없이 하나의 묶음으로 저장하는 형태의 컬렉션 타입이다. 세트 내의 값은 모두 유일한 값, 즉 중복된 값이 존재하지 않는다.

// 세트 선언하기
var numbers : Set<Int> = Set<Int>()
var numbers : Set<Int> = []
var numbers : Set<Int> = [100, 200, 300]

비어있는 세트를 선언할 때 대괄호 ``[]``를 사용하는데, 이 때문에 타입추론을 사용할 경우 세트가 아닌 ``Array``로 타입을 지정한다.
// 값 추가하기
numbers.insert(400)
numbers.insert(500)
numbers.insert(500)
numbers.insert(500)
print(numbers)
[400, 500, 300, 200, 100]

위 코드처럼 만약 같은 값을 여러 번 추가할 경우, 세트는 중복된 값을 허용하지 않기 때문에 하나만 추가된다.
// 값 지우기
numbers.remove(100)
print(numbers)
[500, 300, 200, 400]
profile
나 애기 개발자 👶🏻

0개의 댓글