Dictionary
딕셔너리는 배열, 튜플과 달리 순서없는 데이터의 모음이다. 단, 데이터는 '키-값'의 한쌍으로 구분된다.
따라서 딕셔너리의 선언은 키의 자료형과 값의 자료형을 명시하여 선언한다.
var 딕셔너리이름 : Dictionary< 키자료형 : 값자료형 > = [키1:값, 키2:값, 키3:값, ... ]
값은 중복할 수 있으나, 키는 값을 호출하는데에 사용하기에 중첩할 수 없다.
//선언 및 생성
var dic:Dictionary<String:String> = ["red":"빨강","blue":"파랑","green":"파랑","yellow":"노랑"]
//키는 중첩되면 안된다.
print(dic) //딕셔너리는 순서가 랜덤하게 출력된다.
딕셔너리의 출력 결과를 보면 순서없이 출력되는 모습을 볼 수 있다.
선언 및 초기화
선언 및 초기화에는 여러가지 방법들이 있다.
//선언 및 비어있는 형태로 생성
var dic2:[String:Int] = [:] //String형태의 키, Int형태의 값으로 생성.
print(dic2)
var dic3:Dictionary<Int,Int> = [:] //Int형태의 키, Int형태의 값으로 생성.
print(dic3)
dic3 = [3:100,7:200,10:5] //키-값 대입하여 초기화
print(dic3)
var dic4 = [String:String]() //비어있는 형태로 생성
print(dic4)
var dic5 = Dictionary<Int,String>() //비어있는 형태로 생성
print(dic5)
원소 호출
딕셔너리의 원소(값)의 호출방법이다. 키를 이용하여 호출 및 접근한다.
//원소호출
//print(dic[0]) 딕셔너리는 순서가 없다.
print("dic[\"red\"]:",dic["red"]!) //옵셔널로 반환된다. 값이 없을수도 있기에
print("dic[\"pink\"]:",dic["pink"]) //없는 키를 출력시 nil이 출력된다.(옵셔널)
기본적으로 출력 형태는 옵셔널로 출력된다. 키와 값의 존재유무가 확실하지 않기 때문이다.
추가 및 대입
딕셔너리는 튜플과 달리 원소의 추가가 가능하며, 기존의 키에 해당하는 값의 변경 또한 가능하다.
//대입 및 추가
dic["yellow"] = "누렁이" //기존의 키에 새로운 값 대입
dic["orange"] = "주황" //'키-값'의 추가도 가능하다.
print(dic)
삭제
대입 및 추가와 같이 키를 사용하여 값을 삭제할 수 있다.
//삭제
print(dic) //기존 배열 출력
dic.removeValue(forKey: "green") //green 키-값 삭제
print(dic) //삭제된 배열 출력
출력
딕셔너리또한 반복문과 사용하면 편리하게 출력 및 제어할 수 있다.
//개별 출력
for i in dic {
print(i) //튜플형태로 출력된다.
print(i.key, i.value) //키와 값을 따로 출력할 수 있다.
}
print("------------\n")
for (k, v) in dic{
print(k,v) //키와 값을 더 간략하게 출력할 수 있는 방법이다.
}
var k = dic.keys //키만 따로 뽑아낼 수 있다.
print(k) //배열형태로 출력된다.
var v = dic.values //값만 따로 뽑아낼 수 있다.
print(v) //배열형태로 출력된다.
메소드
딕셔너리의 여러가지 메소드를 통해 데이터를 반환받을 수 있다.
//비어있는 딕셔너리인지 확인
print(dic.isEmpty)
//딕셔너리의 갯수 출력
print(dic.count)
//딕셔너리 비우기
dic.removeAll()
print(dic.isEmpty)
print(dic.count)
Dictionary 예제
중복된 숫자의 배열을 받아서 각 숫자가 몇번 중복되었는지 딕셔너리형태로 출력해보자.
let hit = [3,4,7,8,1,3,5,7,1,3,4,8,1,1] //안타 친 등번호 순서
var hitData = [Int:Int]() //비어있는 딕셔너리 생성
for i in hit{
var no = 1
// print(i, hitData[i]==nil) //해당 데이터가 중복인지 확인.
if hitData[i] != nil{ //중복된 자료라면,
no += hitData[i]! //hitData[i]의 값을 1증가한다.
}
hitData[i] = no //중복이 되지 않으면서 대입이 된다.
}
print(hit) //기존 데이터 출력
print(hitData) //[등번호 : 안타횟수] 형태로 출력
[번호 : 중복횟수] 형태로 출력이 되지만, 딕셔너리는 순서없는 자료형이기에, 랜덤하게 출력이 된다. 오름차순으로 정렬하려면 따로 가공하여 출력해야한다.
//dictionary는 순서없는 자료형이기에, sort()함수는 불가능. sorted()함수를 이용하여 정렬된 자료를 반환받아 처리해야한다.
for k in hitData.keys.sorted(){
print("\(k):\(hitData[k]!)개","",separator: "\t",terminator: "") //등번호, 안타횟수 출력
}
최종출력은 다음과 같다. print()함수의 separactor 속성은 다음 데이터 출력 시 기존 데이터와 구분하기 위해 출력내용을 정해주는 속성이다. 한번에 데이터가 두개 이상 출력이 되어야 적용되므로 기존 자료와 공백 데이터("")를 출력하게 작성했다.
Set
딕셔너리는 키와 값으로 이루어진 순서없는 데이터의 모음(컬렉션 타입)이다. 하지만 키-값 쌍의 형태가 아닌 단일형태의 순서없는 데이터 모음이 필요한 경우 Set을 사용한다. 즉 키로만 이루어진 딕셔너리라고 생각하면 된다.
var 변수이름 : Set<자료형> = [자료,자료,자료]
var arr = [11,22,11,33,22,44,11,55] //배열 중복데이터가 허용된다. 순서가 있다.
var ss1:Set<Int> = [11,22,11,33,22,44,11,55] //set 중복데이터는 생략되어 저장된다. 순서가 없다.
print(arr)
print(ss1)
값으로 이루어진 딕셔너리가 아닌 키로만 이루어진 모임이라고 설명한 것은 바로 데이터의 중복이 허용되지 않는다는 점 때문이다. 일반적인 배열과 큰 차이이다. 출력 모습도 배열은 인덱스 순서로 출력되는 반면, set은 순서없이 출력이 되는 모습을 볼 수 있다.
선언 및 초기화
var ss2 = Set<String>() //빈 set생성
var ss3:Set<Int> = [] //빈 set생성
print(ss2)
print(ss3)
ss2 = ["a","b","d"] //빈 set 초기화
ss3 = [3,4,4,5,6,7] //빈 set 초기화
print(ss2)
print(ss3)
요소 갯수 출력
var ss1:Set<Int> = [11,22,11,33,22,44,11,55]
//set 요소 갯수출력
print(ss1.count)
중복이 허용되지 않아 ss1의 요소는 5개로 출력한다.
반복문 출력
var ss1:Set<Int> = [11,22,11,33,22,44,11,55]
//반복문 출력
for i in ss1 {
print(i) //원소를 하나씩 가지고 올 수 없다. 순서가 없기 때문이다.
}
Set은 배열과 달리 인덱스가 없기에 반복문을 통해 요소를 하나씩 출력할 수 없다.
요소 검색, 추가, 삭제
var ss1:Set<Int> = [11,22,11,33,22,44,11,55]
//요소 검색
print(ss1.contains(33)) //요소 33이 있는가?
print(ss1.contains(100))//요소 100이 있는가?
//요소 추가
ss1.insert(77) //요소 77 추가 *중복데이터를 추가하면 변화가 일어나지 않는다.
print(ss1)
//요소 삭제
ss1.remove(22) //요소 22 삭제
print(ss1)
isEmpty, 전체삭제
var ss1:Set<Int> = [11,22,11,33,22,44,11,55]
//빈 set인지 확인
print(ss1.isEmpty) //bool return
//요소 전체삭제
ss1.removeAll() //요소 전체삭제
print(ss1.isEmpty)
isEmpty메소드를 통해 비어있는 배열인지 확인 후 bool값을 반환해준다.
set 집합연산
set에는 여러가지 집합연산이 메소드 형태로 존재한다.
var s1 : Set<Int> = [1,2,3,4,5,6] //순서없는 자료 묶음
var s2 : Set<Int> = [4,5,6,7,8,9]
print("s1 \(s1)")
print("s2 \(s2)")
var rr = s1.union(s2) //합집합
print("s1.union(s2) \(rr)")
rr = s1.intersection(s2) //교집합
print("s1.intersection(s2) \(rr)")
rr = s1.symmetricDifference(s2) //합집합 - 교집합
print("s1.symmetricDifference(s2) \(rr)")
rr = s1.subtracting(s2) //s1 차집합 s2
print("s1.subtracting(s2) \(rr)")
rr = s2.subtracting(s1) //s2 차집합 s1
print("s2.subtracting(s1) \(rr)")
set 예제1
set을 사용하여 로또 번호 생성기를 작성해보자.
var lotto1 = [Int]()
var lotto2 = Set<Int>()
while true {
let no = Int.random(in: 1...45) //1부터 45까지 랜덤번호 생성 메소드
lotto1.append(no) //배열에 요소 추가
lotto2.insert(no) //set에 요소 추가
if lotto2.count == 7 { //set의 요소가 7개가 되면 종료
break
}
}
print("lotto1: \(lotto1)") //배열의 경우 겹치는 수가 존재한다.
print("lotto2: \(lotto2)") //set의 경우 겹치는 수가 없다.
배열과의 비교를 통해 두개를 작성했다. 배열의 경우 중복이 허용되기 때문에 중복된 숫자가 생성된다. 하지만 set의 경우 중복을 허용하지 않기에 요소가 7개가 될 때 반복문을 탈출하면 된다.
set 예제2
set을 이용하여 빙고판을 만들어 보자.
var number = Set<Int>()
var cnt = 0
while number.count < 25{ //set의 요소가 25가 될때까지 랜덤숫자 삽입
number.insert(Int.random(in: 1...100))
}
for i in number{
cnt += 1
print(i,terminator: "\t") //줄 변경 없이 출력
if cnt % 5 == 0 { //cnt가 5의 배수가 되면 줄 변경
print()
}
}
set의 중복 불허용의 특성을 이용하여 5x5 숫자빙고를 출력하였다.
set 예제3
각 리스트의 중복을 제거하는 예제이다.
let first:Set<String> = ["박재상","박정권", "최정", "김광현", "엄정욱", "박희수", "이호준"]
let second:Set<String> = ["이호준", "엄정욱", "박재홍", "이신협", "장동건"]
let fa:Set<String> = ["이병규", "이승엽", "박정권", "장동건", "박용택", "홍성흔"]
print("변경 전---------------------------")
print("1군 리스트:",first)
print("2군 리스트:",second)
print("FA 리스트:",fa)
let afterFirst = first.subtracting(second).subtracting(fa) //1군 - 2군 - FA
let afterSecond = second.subtracting(fa) //2군 - FA
let afterFa = fa.subtracting(first).subtracting(second) //FA - 1군 - 2군
print("변경 후---------------------------")
print("1군 리스트:",afterFirst)
print("2군 리스트:",afterSecond)
print("FA가능 리스트:",afterFa)
야구를 안봐서 뭐하는 예제인지는 모르겠다.
'iOS > TJ' 카테고리의 다른 글
day11_param, return, funcCall (0) | 2021.06.18 |
---|---|
day10_func() (0) | 2021.06.17 |
day08_multiArray, tuple (0) | 2021.06.03 |
day07_array (0) | 2021.06.02 |
day06_control flow_loop (0) | 2021.05.27 |