일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 깃헙
- 클로저
- viewDidDisappear
- 알뜰폰
- 아이폰
- without Storyboard
- 스위프트
- git
- swift haptic
- indicator style
- 런치 스크린
- loadView
- 세븐모바일
- 뷰컨
- graceful termination
- scroll indicator
- 우아한 앱종료
- viewWillDisappear
- 레이아웃 사이클
- viewDidAppear
- refreshControl
- do try catch
- IOS
- SWIFT
- 스크롤 인디케이터
- exit()
- 이니셜라이저
- viewcontroller
- FeedbackGenerator
- 스토리보드
- Today
- Total
예거's Bicycle for the mind
[Swift] Nested Array (2차원 배열)에서 튜플을 이용해 다중 정렬하는 법 (sort, tuple, Closure) 본문
[Swift] Nested Array (2차원 배열)에서 튜플을 이용해 다중 정렬하는 법 (sort, tuple, Closure)
유예거 2021. 9. 30. 18:53스위프트 Array(배열)은 순서가 있는 Ordered Collection Type 이다.
Array를 2중으로 만들어서 정렬(sort)을 공부해보자.
먼저, sort() 와 sorted() 정렬 메소드의 차이를 알아야 한다.
sort 는 원본값에 영향을 주고 리턴값이 없다.
sorted 는 원본값에 영향을 주지 않고, 새로운 리턴값을 반환한다.
즉 let 으로 선언한 배열이 있다면, sort 메소드를 사용할 수 없다.
let 으로 선언한 배열은 'immutable value' 가 된다. 즉, 변경이 불가능한 값! 따라서 원본을 건드리는 sort() 메소드를 쓸 수 없다.
만약 원본이 변경되길 원하지 않는 배열이 있다면, let 으로 선언한 뒤 sorted() 메소드로 새로운 값을 만들어 쓰는 게 좋다.
배열 예시를 만들고 sorted() 메소드를 붙여서 간단하게 정렬해보자.
// 정렬 실험을 위한 배열 예시 생성
let subjects = ["나", "바", "다", "가", "라", "마"]
let grades = ["C", "A", "B"]
subjects.sorted()
// ["가", "나", "다", "라", "마", "바"] -> 가나다 정렬됨
grades.sorted()
// ["A", "B", "C"] -> ABC 정렬됨
정렬에 아무 조건을 걸지 않는다면
한글 String 에서는 가나다 순서대로, 영문 String 에서는 알파벳 순서대로 '오름차순' 정렬된다.
그러면 2차원 배열인 [[String]] 예시를 만들어보자. 여러 번 중첩된 배열은 Nested Array 라고도 부른다.
Nest 는 새의 둥지를 말하는데, Nested 는 "중첩된" 이란 의미가 된다.
그 의미를 이해하기 위해선 아래 이미지를 참고해보자. 새둥지는 여러 겹의 나뭇가지로 만들어져 있다.
여러 겹으로 둘러 쌓인 모습을 Nested 라고 생각하면 쉽다.
Nested 는 Array 뿐만 아니라, 어떤 단어에도 붙을 수 있다.
실제로 스위프트 문법에서도 얼마든지 Nested Types(중첩 타입), Nested Functions(중첩 함수), Nested Enums(중첩 열거형) 등을 만들어낼 수 있다.
다시 본론으로 돌아와서, 중첩 배열인 [[String]] 을 만들어서 갖고 놀아보자.
// [[String]] 생성!
// 가나다라마바 라는 과목명과 학점 ABC를 배열로 묶어서 다시 배열에 넣은 형태다.
let myGrades = [
["B", "다"],
["A", "바"],
["C", "나"],
["B", "가"],
["A", "라"],
["A", "마"]
]
myGrades.sorted()
// 컴파일 에러!
// -> '[String]'이 'Comparable' 프로토콜을 준수하지 않기에 정렬할 수 없음
일부로 가나다라마바와 ABC 순서가 엉망으로 섞이도록 만들었다.
let 으로 선언한 myGrades 에다가 sorted() 메소드를 적용해보면 컴파일 에러가 뜬다.
왜? String 타입은 Comparable 프로토콜을 준수하지만, String 이 배열 안에 들어간 [String] 은 그 프로토콜을 준수하지 않기 때문이다.
프로토콜 Comparable
: A type that can be compared using the relational operators <, <=, >=, and >.
그렇다면 [String]을 파고 들어서 정렬 조건을 걸어보자.
클로저와 단축인자이름($)을 사용해보자.
// 후행 클로저(Trailing Closure)와 단축인자이름(Shorthand Argument Names) 사용
print(myGrades.sorted { $0[0] < $1[0] })
// [["A", "바"], ["A", "라"], ["A", "마"], ["B", "다"], ["B", "가"], ["C", "나"]]
// 또는 아래와 같은 문법도 모두 같은 결과를 낸다.
print(myGrades.sorted(by:) { $0[0] > $1[0] })
print(myGrades.sorted(by: { $0[0] > $1[0] }))
ABC 순서대로 정렬됐지만, 바로 뒤에 붙는 바라마다가나 가 엉망이다.
ABC 정렬을 1순위 정렬로 하고, 그 다음엔 2순위 정렬로 가나다 정렬을 하고 싶다면 어떻게 해야할까?
클로저 안에 튜플(Tuple)의 값의 비교를 응용해서 정렬의 우선순위를 만들어보자.
튜플의 값 비교는 어떻게 작동하는 걸까?
예시를 통해 공부해보자.
// 튜플의 값 비교 예시
("가", 3) < ("나", 2) // true -> 앞에서 판단 끝
("나", 3) < ("가", 1) // false -> 앞에서 판단 끝
("가", 2) < ("가", 3) // true -> 앞이 동일하면 뒤에서 2순위 판단
("가", 2) < ("가", 3, 5) // 컴파일 에러 -> 튜플의 사이즈가 다름
("가", 2) < ("가", "3") // 컴파일 에러 -> 튜플의 타입이 다름
튜플끼리 값의 비교를 할 때는, 앞 요소끼리 각각 순서대로 크기 비교를 할 수 있다.
이 특징을 활용해보자.
// 튜플의 값 비교를 응용한 정렬의 우선순위 부여
print(myGrades.sorted { ($0[0], $0[1]) < ($1[0], $1[1]) })
// [["A", "라"], ["A", "마"], ["A", "바"], ["B", "가"], ["B", "다"], ["C", "나"]]
// ABC 순서가 1순위, 가나다 순서가 2순위로 적용됨
ABC 1순위, 가나다 2순위로 배열들이 정렬된 것을 확인할 수 있다.
그럼 만약, ABC 순서는 유지하고, 2순위 가나다 정렬을 거꾸로 하고 싶다면 어떻게 해야할까?
print(myGrades.sorted { ($0[0] < $1[0]) || ($0[1] > $1[1]) })
// [["A", "바"], ["A", "마"], ["A", "라"], ["B", "다"], ["B", "가"], ["C", "나"]]
클로저 안에 각각 값비교를 한 뒤에 OR(또는)를 의미하는 Logical operator 인 || 를 사용해서
ABC 순서를 유지하면서 가나다를 거꾸로 적용했다.
일단 결과는 얻어냈지만, 아직 나의 모자란 스위프트 문법 실력으로는 이 원리를 잘 모르겠다. 🥺
'iOS & Swift' 카테고리의 다른 글
[Swift] NameSpace(네임스페이스)란 무엇이고, 어떻게 만들면 좋을까? (3) | 2021.10.17 |
---|---|
[Swift] 큰 숫자를 다룰 때 underscore(_)를 이용해 자릿수 표기하는 법 (0) | 2021.10.10 |
[Swift] 고차함수 map, compactMap 의 차이와 활용법 (0) | 2021.10.10 |
[Swift] Dictionary 의 옵셔널 반환에 대응하는 법 (default, nil 병합연산자) (1) | 2021.09.29 |
[야곰 아카데미] iOS 개발자가 되기 위한 첫 단추 (6) | 2021.09.06 |