Kotlin 간단한 정렬과 복잡한 정렬

Minseok·2020년 12월 23일
1
post-thumbnail

코틀린에서는 일반적으로 간단한 정렬을 위해 Iterable<T>.sortedBy(...) 를 사용합니다. 하지만 실제로 기획에 있어서 간단한 정렬만 있는 것이 아닙니다. 다양한 정렬 방법이 필요합니다. SortedWith 를 사용한다면 복잡한 형태의 정렬도 가능합니다.

TLTR;

class Person(val name: String, val age: Int, val score: Int)
var sortedPeople = emptyList<Person>()

val people = listOf(
        Person("김복남", 20, 90),
        Person("김점례", 21, 80),
        Person("황덕순", 21, 70),
        Person("이흥복", 22, 80),
        Person("이덕출", 20, 80)
)


// 정렬 : 기본 정렬
sortedPeople = people.sortedBy(Person::age)


// 정렬 : 2개 이상의 요소로 정렬
sortedPeople = people.sortedWith(
        compareByDescending(Person::age)
                .thenByDescending(Person::score)
)

기본 정렬

사람들을 나이가 어린 순으로 정렬하고자 합니다.
보편적으로 사용하는 sortedBy 를 이용해서 정렬하면 됩니다. 코드는 다음과 같습니다.

data class Person(val name: String, val age: Int, val score = 0)

val people = listOf(
        Person("김복남", 20),
        Person("김점례", 21),
        Person("황덕순", 21),
        Person("이흥복", 22),
        Person("이덕출", 20)
)

people.sortedBy(Person::name).toPrint()

// Person(name=김복남, age=20)
// Person(name=이덕출, age=20)
// Person(name=김점례, age=21)
// Person(name=황덕순, age=21)
// Person(name=이흥복, age=22)

fun <T> List<T>.toPrint() { this.forEach(::println) }

기준이 2개 이상인 정렬

위 예제 같은 경우는 나이 순으로는 정렬이 되었습니다. 추가로 프로퍼티가 하나 더 생길 경우에도 그 프로퍼티와 상관 없이 나이 순으로만 정렬 됩니다. 그럼 새로운 프로퍼티를 가지고 정렬 조건을 추가하고 싶을 땐 어떻게 하면 될까요? 2개 이상의 기준으로 정렬할 땐 Iterable<T>.sortedWith(…): List<T> 를 사용하면 됩니다.

사람을 2명 뽑는다고 가정해봅니다. 아무나 뽑을 순 없으니 나이가 많고, 사람마다 점수를 부여하여 점수가 높은 순으로 선발하려고 합니다. 기준이 1개 있을 때와 다르게 조건이 [나이를 내림차순 한다][점수를 내림차순 한다] 이렇게 두가지 조건이 붙었습니다. 이런 경우에는 다음과 같이 해결 할 수 있습니다.

data class Person(val name: String, val age: Int, val score = 0)

val people = listOf(
		Person("김복남", 20, 90),
		Person("김점례", 21, 80),
		Person("황덕순", 21, 70),
		Person("이흥복", 22, 80),
		Person("이덕출", 20, 80)
)

people.sortedWith(
        compareByDescending(Person::age)
                .thenByDescending(Person::score)
).toPrint()

// Person(name=이흥복, age=22, score=80)
// Person(name=김점례, age=21, score=80)
// Person(name=황덕순, age=21, score=70)
// Person(name=김복남, age=20, score=90)
// Person(name=이덕출, age=20, score=80)

fun <T> List<T>.toPrint() { this.forEach(::println) }
profile
Android Developer

0개의 댓글