본문 바로가기
2023년 이전/swift

튜플,배열, 딕셔너리,세트, 열거형

by JeongUPark 2020. 7. 5.
반응형

swift 공부를 하면서 정리한 내용 입니다. 본 내용은 스위프트 프로그래밍 3판 (야곰 지음) 을 공부하면서 정리한 내용입니다.

 

튜플

튜플은 지정된 데이터 묶음을 말합니다.

var person : (String,Int,Double) = ("jeongu", 34, 176.3)
print("이름 : \(person.0), 나이 : \(person.1), 키: \(person.2)")

var person : (name: String, age: Int, height: Double) = ("jeongu", 34, 176.3)
print("이름 : \(person.name), 나이 : \(person.age), 키: \(person.height)")

위의 코드처럼 데이터 묶음을 만들 수 있고, 각 요소를 숫자로 표현합니다. 하지만 숫자로 표현한다면 다른 사람이 봤을 때 바로 알 수 없을 수도 있기 때문에 아래 처럼 요소마다 이름을 붙여 줄 수 도 있습니다.

 

배열

배열은 데이터를 일열로 나열 한 후 순서대로 저장하는 형태입니다. 한번 만들었다고 그 크기가 고정되는 것이 아니라 삽입 삭제가 자유롭습니다.

var names: Array<String> = ["AAAA","BBBB","CCCC"]
// 또는 var names : [String] = ["AAAA","BBBB",CCCC"]

//추가
print(names)
names.append("DDDD")
print(names)
// array로 추가
names.append(contentsOf: ["EEEE","FFFF"])
print(names)
// 특정 위치 삭제
names.remove(at: 1)
print(names)
// 특정 위치 삽입
names.insert("BBBB", at: 1)
print(names)
// 첫번쨰 삭제
names.removeFirst()
print(names)
// 마지막 삭제
names.removeLast()
print(names)
// 마지막에서 몇개 삭제
names.removeLast(2)
print(names)

결과는 

["AAAA", "BBBB", "CCCC"]  // default
["AAAA", "BBBB", "CCCC", "DDDD"] // append
["AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF"] // append contentOf
["AAAA", "CCCC", "DDDD", "EEEE", "FFFF"] // remove at
["AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF"] //insert at
["BBBB", "CCCC", "DDDD", "EEEE", "FFFF"] // removeFirst
["BBBB", "CCCC", "DDDD", "EEEE"] // removeLast
["BBBB", "CCCC"] // removeLast lenght

딕셔너리

딕셔너리는 요소들이 순서 없이 키와 값의 쌍으로 구성되는 컬렉션 타입입니다. 딕셔너리는 항상 키와 값의 쌍을 이루는데 이 쌍은 여러개가 가능하지만 키는 중복해서 사용할 수 없습니다. (값은 중복되도 됩니다.)

typealias StringIntDictionary = [String : Int]

//var numberForName : Dictionary<String , Int> = Dictionary<String,Int>()
//var numberForName : [String: Int] = [String:Int]()
var numberForName : StringIntDictionary = StringIntDictionary()
numberForName = ["jeongu":100, "aaa":200, "bbb":300]

print(numberForName["jeongu"] ?? 0)

위처럼 딕셔너리를 만들 수 있고, 지금 print에서 키 값으로 string 인 jeongu를 호출해서 그 값이 100이 노출 됩니다.

numberForName.removeValue(forKey: "jeongu")
print(numberForName)

위와 같이 value를 통하여 그 값을 지울 수 있습니다. print 결과는 

["bbb": 300, "aaa": 200]

이렇습니다.

 

세트

세트는 같은 타입의 데이터를 순서 없이 하나로 묶는 컬렉션 타입으로, 세트 내의 값은 모두 유일한 값입니다. 즉, 중복되는 값이 존재하지 않습니다. 그래서 순서가 중요하지 않고 각 요소가 유일해야할 때 사용합니다.

//var names: Set<String> = Set<String>()  // 빈 세트 생성
//var names: Set<String> = []             // 빈 세트 생성

var names: Set<String> = ["yagom", "chulsoo", "younghee", "yagom"]  // Array와 마찬가지로 대괄호를 사용합니다.
// 그렇기 때문에 타입 추론을 사용하게 되면 컴파일러는 Set가 아닌 Array로 타입을 지정합니다.
print(type(of: names))  
print(names.count)      // 3 - 중복된 값은 허용되지 않아 yagom은 1개만 남습니다.
print(names.count)          // 3
names.insert("jenny")
print(names.count)          // 4
print(names.remove("chulsoo"))      // chulsoo
print(names.remove("john"))         // nil
print(names.count)

위의 print들은 다음과 같이 나타납니다.

Set<String>
3
3
4
Optional("chulsoo")
nil
3

옵셔널을 지우려면 print(names.remove("chulsoo") ?? "") 이렇게 작성해주면 됩니다.

 

열거형

열거형은 연관된 항목들을 묶어서 표현할수 있는 타입니다. emun을 생각하시면 됩니다. 보통 열거형은 

제한된 선택지를 주고싶을 떄, 정해진 값 외에 입력받고 싶지 않을 때, 예상된 입력 값이 한정되어 있을 때 주로 사용 합니다.

열거형은 다음과 같이 선언 합니다.

enum School {
    case primary        // 유치원
    case elementary     // 초등
    case middle         // 중등
    case high           // 고등
    case college        // 대학
    case university     // 대학교
    case graduate       // 대학원
}
// or
enum School {
    case primary, elementary, middle, high, college, university, graduate
}

그리고 위처럼 항목 자체로도 하나의 값이 되지만 원시값(Raw Value)를 줄 수 도 있습니다.

enum School: String {
    case primary = "유치원"
    case elementary = "초등학교"
    case middle = "중학교"
    case high = "고등학교"
    case college = "대학"
    case university = "대학교"
    case graduate = "대학원"
}

그래서 다음과 같이 값을 출력해 보면

print("\(School.college)")   // college
print("\(School.college.rawValue)") //대학

출력이 됩니다.

그리고 모든 값이 원시값을 가질 필요는 없습니다.

enum Numbers: Int {
    case zero
    case one
    case two
    case ten = 10
}
print(Numbers.zero.rawValue) // 0 
print(Numbers.one.rawValue)  // 1
print(Numbers.two.rawValue) // 2
print(Numbers.ten.rawValue) // 10 만약 원시값 10을 지정하지 않았다면 3

열거형-연관값

스위프트의 열거형 각 항목이 연관 값을 가지게 되면, 기존 프로그래밍 언어의 공요에 형태를 띌 수 도 있습니다. (연관 값은 각 항목 옆에 소괄호로 묶어 표현할 수 있숩니다. 그리고 다른 항목이 연관값을 가진다고 모든 항목이 그럴 필요는 없습니다.)

enum PastaTaste {
    case cream, tomato
}

enum PizzaDough {
    case cheeseCrust, thin, original
}

enum PizzaTopping {
    case pepperoni, cheese, bacon
}

enum MainDish {
    case pasta(taste: PastaTaste)
    case pizza(dough: PizzaDough, topping: PizzaTopping)
    case chicken(withSauce: Bool)
    case rice
}

var dinner: MainDish = MainDish.pasta(taste: PastaTaste.tomato)
dinner = MainDish.pizza(dough: PizzaDough.cheeseCrust, topping: PizzaTopping.bacon)

열거형-항목 순회

때떄론 열거형에 포함된 모든 케이스를 알아야할 떄가 있습니다. 이럴 때는 열거형의 이름 뒤에 : Caselterable을 선언해줍니다. 그러면 allCases라는 이름의 타입 프로퍼티를 통해 모든 케이스의 컬렉션을 생성해줍니다. 원시형을 갖는 열거형이라면 타입 다음에 쉽표(,) 뒤에 CaseIterable을 선언해주면 됩니다.

 

enum School: String, CaseIterable {
    case primary = "유치원"
    case elementary = "초등학교"
    case middle = "중학교"
    case high = "고등학교"
    case college = "대학"
    case university = "대학교"
    case graduate = "대학원"
}

let allCases: [School] = School.allCases
print(allCases)

그리고 열거형은 플랫폼 별로 사용조건을 추가하거나 케이스가 연관 값을 갖는 경우 allCases 프로퍼티를 바로 사용할 수 가 없습니다. 그럴떄는 조건을 추가하여야 합니다.  그렇기 때문에 allCases 한번더 확인이 필요합니다.

 

열거형 - 순환 열거형

순환 열겨형은 열거형 항목의 연관 값이 열거형 자신의 값이 고자할 때 사용합니다. (먼가 피보나치 느낌이 강합니다.) 순환 열거형을 명시하고 싶다면 indirect 키워드를 사용하면 됩니다. 특정항목에만 사용하고 싶다면 case앞에 전체에 적용하고싶다면 enum 앞에 사용하면 됩니다.

indirect enum ArithmeticExpression {
    case number(Int)
    case addition(ArithmeticExpression, ArithmeticExpression)
    case multiplication(ArithmeticExpression, ArithmeticExpression)
}

let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let final = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))

func evaluate(_ expression: ArithmeticExpression) -> Int {
    switch expression {
    case .number(let value):
        return value
    case .addition(let left, let right):
        return evaluate(left) + evaluate(right)
    case .multiplication(let left, let right):
        return evaluate(left) * evaluate(right)
    }
}

let result: Int = evaluate(final)
print("(5 + 4) * 2 = \(result)")

위에서 evaluate은 ArithmeticExpression을 확인해 계산을 도와주는 함수 입니다. evluate에 final이 들어가면

expression이 multiplication이 되고, 그 안에 left 값인 sum과 right 값인 ArithmeticExpression.number(2) 가 각가 또 evaluate에 Input 됩니다. 그렇게 분석을 하면

evaluate (evaluate(evaluate(ArithmeticExpression.number(5)) + evaluate(ArithmeticExpression.number(4))) * evaluate()ArithmeticExpression.number(2))

이렇게 계산 됩니다.

반응형

'2023년 이전 > swift' 카테고리의 다른 글

music player 만들기  (0) 2020.09.20
클로저  (0) 2020.08.30
구문 이름표  (0) 2020.07.12
swift의switch 문  (0) 2020.07.12