티스토리 뷰

반응형

 

안녕하세요 :) Zedd입니다.

정렬 (2)에서 2가지 기준으로 정렬하는 것을 공부해봤는데, 오늘은 3가지 기준으로 정렬하는 법을 알아보겠습니다.

저번과 거의 비슷합니다.

struct PullRequest {
    
    var title: String
    var createdDate: Date
    var approved: Bool
    var hasPriority: Bool
}

다만 hasPrioirty 프로퍼티가 추가되었습니다.

정렬(2)에서 기준이

1. 오래된 순으로 정렬.

2. approve된것은 가장 하단에.

였다면 이번에는 조건이 하나 더 추가됩니다.

3. approve유무와 상관없이 hasPrioirty가 true면 가장 위로 보낸다. 

입니다.

let pullRequests = [
    PullRequest(title: "알렌 워커", createdDate: Calendar.current.date(byAdding: .day, value: -1, to: Date())!, approved: true, hasPriority: true),
    PullRequest(title: "카이고", createdDate: Calendar.current.date(byAdding: .day, value: -2, to: Date())!, approved: false, hasPriority: true),
    PullRequest(title: "마시멜로우", createdDate: Calendar.current.date(byAdding: .day, value: -3, to: Date())!, approved: false, hasPriority: false),
    PullRequest(title: "제드", createdDate: Calendar.current.date(byAdding: .day, value: -4, to: Date())!, approved: true, hasPriority: false),
    PullRequest(title: "마데온", createdDate: Calendar.current.date(byAdding: .day, value: -5, to: Date())!, approved: false, hasPriority: false),
    PullRequest(title: "마틴개릭스", createdDate: Calendar.current.date(byAdding: .day, value: -5, to: Date())!, approved: true, hasPriority: true)
]

title : PR제목
createdDate: 만들어진 날짜
approved: approve 여부
hasPrioirty: Prioirty 여부

 

# 과정

가장 중요한건 hasPrioirty가 True이면 무조건 앞으로 보내야한다는 것입니다.

✅ : approved

⬆️ : hasPrioirty

 

그럼 hasPrioirty로 먼저 검사를 해보겠습니다.

let sorted = pullRequests.sorted { (first, second) -> Bool in
    if first.hasPriority != second.hasPriority {
    	return ??
    } 
    return ??
 }

first와 second의 hasPrioirty가 다를 때 어떻게 할지 정해보겠습니다.

(정렬을 하는 방법이 위와같이 hasPrioirty가 다를때 검사 한다! 말고 다양한 방법이 있을 수 있습니다)

알렌워커와 카이고 모두 hasPrioirty가 True로 같으니 넘어가고, 

여기서 시작해보겠습니다.

first: 마시멜로우

second : 카이고 

마시멜로우의 hasPrioirty는 false이고

카이고의 hasPrioirty는 true이기 때문에 위치를 바꿔서는 안됩니다.

즉, false를 리턴해야하죠.

정렬(2)에서 본 것 처럼 무조건 false를 리턴해도 안됩니다.

이때는 true를 리턴하여 순서를 바꿔주어야 하기 때문입니다.

그렇다면 역시..

let sorted = pullRequests.sorted { (first, second) -> Bool in
    if first.hasPriority != second.hasPriority {
    	return !second.hasPriority
    } 
    return ??
 }

second의 hasPrioirty가 true이면 false를 리턴하고, false이면 true를 리턴하도록 해줍니다.

 

이제 아래 return값이 무엇이 되든

hasPrioirty가 true인것은 위로 올라오게 됩니다.

1. 오래된 순으로 정렬.

2. approve된것은 가장 하단에.

3. approve유무와 상관없이 hasPrioirty가 true면 가장 위로 보낸다. 

 

3번을 만족시켰으니 1, 2를 만족시키면 됩니다. 이건 정렬(2)에서 한거랑 똑같습니다!! 

let sorted = pullRequests.sorted { (first, second) -> Bool in
    if first.approved != second.approved {
        return !first.approved
    }
    return first.createdDate < second.createdDate
}

이 조건문들을 넣어주면 됩니다.

결과적으로 최종 코드는 이렇게 됩니다.

let sorted = pullRequests.sorted { (first, second) -> Bool in
    if first.hasPriority != second.hasPriority {
        return !second.hasPriority
    } else {
        if first.approved != second.approved {
            return !first.approved
        }
        return first.createdDate < second.createdDate
    }
}

설명은 정렬(2)에서 했으니 생략하겠습니다.

 

# 결과

결과입니다.

approve유무와 상관없이 hasPrioirty가 true면 가장 위로 보내졌고 ✅

 

approve안된 것들은 오래된 순으로 정렬되었고

 

approve된것은 가장 하단에 위치하게 되었습니다

 

# Q&A

Q : 

여기서도 오래된순으로 정렬되었으면 좋겠어!

 

A : 뭐 기가막히고 우아한 방법은 생각이 안나고;;

let sorted = pullRequests.sorted { (first, second) -> Bool in
    if first.hasPriority != second.hasPriority {
        return !second.hasPriority
    } else {
        if first.hasPriority {
            return first.createdDate < second.createdDate
        } else if first.approved != second.approved {
            return !first.approved
        }
        return first.createdDate < second.createdDate
    }
}

else문안에서 firs의 hasPrioirity가 true일때를 검사했습니다. (물론 second를 검사해도됩니다)

아마 저 if문은 이때 검사되게 될텐데, 둘다 True인데 카이고가 더 오래전에 만들어졌으니 자리를 바꿔야겠죠.

결과적으로

이렇게 됩니다. hasPrioirity가 true인 것들이 오래된 순으로 정렬되게 되었죠!

 

저는 뭔가 정렬 기준이 2가지 일때는 그냥 타닥-! 해서 바로 했는데,

정렬 기준을 3가지로 잡으려니까 뭔가 머리가 안돌아가더라구요.

역시 글로 정리하니까 완벽히 이해가 갑니다..

제가 하면서 느낀점은 큰 기준 하나로 전체적인 정렬을 끝내고, 나머지, 또 그 나머지..이런식으로 조건을 정리해가다 보면 여러 기준(3개 이상)으로 정렬해야할 때도 쉽게 하실 수 있을 것 같습니다.

궁금한점이나 틀린 부분을 발견하신다면! 댓글 달아주시면 감사하겠습니다.

반응형

'Swift' 카테고리의 다른 글

Unowned Optional References  (11) 2021.02.22
Swift ) ARC / Strong Reference Cycle 해결 방법(weak, unowned)  (4) 2021.02.18
Swift ) 정렬 (2) - Sort by two criteria  (0) 2020.11.24
Swift ) 정렬 (1)  (0) 2020.11.23
Swift 5.3 released!  (3) 2020.09.17