반응형

https://play.kotlinlang.org/koans/Collections/Introduction/Task.kt

 

Kotlin Playground: Edit, Run, Share Kotlin Code Online

 

play.kotlinlang.org

코틀린 공식문서에 있는 Colletions 파트를 읽으며 정리해보았습니다.


Basic Code

Shop.kt 의 코드 구성

data class City(val name: String) {
    override fun toString() = name
}

data class Product(val name: String, val price: Double) {
    override fun toString() = "'$name' for $price"
}

data class Order(val products: List<Product>, val isDelivered: Boolean)

data class Customer(val name: String, val city: City, val orders: List<Order>) {
    override fun toString() = "$name from ${city.name}"
}

data class Shop(val name: String, val customers: List<Customer>)

Sort

Ordering

동일한 원소들을 가진 리스트가 두 개 있어도 원소의 순서가 다르다면 같은 리스트가 아니다. 

코틀린에서 객체의 순서는 여러가지 방법으로 정의가 될 수 있는데 그 중 natural order이라는 것은 Comparable을 상속받아 정의된다. 일반적으로 natural order은 구체적인 정렬기준이 없을 때 사용 된다.

class Version(val major: Int, val minor: Int): Comparable<Version> {
    override fun compareTo(other: Version): Int = when {
        this.major != other.major -> this.major compareTo other.major // compareTo() in the infix form 
        this.minor != other.minor -> this.minor compareTo other.minor
        else -> 0
    }
}

fun main() {    
    println(Version(1, 2) > Version(1, 3)) // pring => false
    println(Version(2, 0) > Version(1, 5)) // print => true
}

 

compare() 포함하고 있는 Comparator을 생성하여 custom order을 정의할 수 있다.

val lengthComparator = Comparator { str1: String, str2: String -> str1.length - str2.length }
println(listOf("aaa", "bb", "c").sortedWith(lengthComparator)) // print => [c, bb, aaa]

lengthComparator로 String을 길이순으로 정렬할 수 있다.

 

Comparator을 짧게 사용하기 위해 standard library에 있는 compareby()함수를 사용할 수 있다. compareby()는 Comparable value를 만들고 custom order을 정의할 수 있는 람다식이다.

println(listOf("aaa", "bb", "c").sortedWith(compareBy { it.length })) // print => [c, bb, aaa]

Natural order

기본적인 함수인 sorted(), sortedDescending()은 컬렉션의 원소를 오름차순, 내림차순으로 정렬하여 반환한다.

이 함수들은 Comparable한 원소들에만 적용이 가능하다.

val numbers = listOf("one", "two", "three", "four")

println("Sorted ascending: ${numbers.sorted()}")
// print => Sorted ascending: [four, one, three, two]
println("Sorted descending: ${numbers.sortedDescending()}")
 // print => Sorted descending: [two, three, one, four]

 


Custom orders

임의로 순서를 정하여 정렬하거나 non-comparable한 객체들을 정렬하기 위해선 sortedBy(), sortedByDescending() 함수가 있다.

원소들을 매핑하여 Comparable한 값으로 바꾸고 natural order로 정렬한ㄷ다.

val numbers = listOf("one", "two", "three", "four")

val sortedNumbers = numbers.sortedBy { it.length }
println("Sorted by length ascending: $sortedNumbers") 
// print => Sorted by length ascending: [one, two, four, three]
val sortedByLast = numbers.sortedByDescending { it.last() }
println("Sorted by the last letter descending: $sortedByLast")
// print => Sorted by the last letter descending: [four, two, one, three]

sortedWith()에 Comparator을 넘기는 것으로도 custom order을 구현할 수 있다.

val numbers = listOf("one", "two", "three", "four")
println("Sorted by length ascending: ${numbers.sortedWith(compareBy { it.length })}")
// print => Sorted by length ascending: [one, two, four, three]

Reverse order

reversed() 함수를 이용하여 역순으로 컬렉션의 값을 가져올 수 있다.

val numbers = listOf("one", "two", "three", "four")
println(numbers.reversed()) // print => [four, three, two, one]

reversed() 함수는 역순으로 정렬된 새로운 컬렉션을 반환한다. == 원래의 컬렉션에는 영향을 미치지 않음.

 

또 다른 함수로는 asReversed()가 있다.

asReversed()는 동일한 컬렉션 객체를 역순 view로 반환해준다. 원래의 list가 바뀌지 않을 것이라면 reversed()보다 조금 더 가볍게 동작한다.

val numbers = listOf("one", "two", "three", "four")
val reversedNumbers = numbers.asReversed()
println(reversedNumbers) // print => [four, three, two, one]

하지만 원래 list가 mutable이고 그것이 바뀌게 된다면 reversed view에서도 마찬가지로 반영이 된다.

val numbers = mutableListOf("one", "two", "three", "four")
val reversedNumbers = numbers.asReversed()
println(reversedNumbers) // print => [four, three, two, one]
numbers.add("five")
println(reversedNumbers) // print => [five, four, three, two, one]

따라서 mutable한 리스트가 수정될 여지가 있다면 reversed()를 사용하는 것이 좋다.


 Random order

Random객체를 사용할 필요없이 컬렉션의 원소들을 랜덤으로 정렬해서 반환해주는 shuffled()함수가 있다.

val numbers = listOf("one", "two", "three", "four")
println(numbers.shuffled()) // print => [two, three, one, four] ...

Basic Code

Shop.kt 의 코드 구성

data class City(val name: String) {
    override fun toString() = name
}

data class Product(val name: String, val price: Double) {
    override fun toString() = "'$name' for $price"
}

data class Order(val products: List<Product>, val isDelivered: Boolean)

data class Customer(val name: String, val city: City, val orders: List<Order>) {
    override fun toString() = "$name from ${city.name}"
}

data class Shop(val name: String, val customers: List<Customer>)

문제

customer 리스트를 order의 수를 기준으로 내림차순으로 정렬하는 확장 함수를 구현하여라.

// Return a list of customers, sorted in the descending by number of orders they have made
fun Shop.getCustomersSortedByOrders(): List<Customer> =

정답

// Return a list of customers, sorted in the descending by number of orders they have made
fun Shop.getCustomersSortedByOrders(): List<Customer> = 
    customers.sortedByDescending{it.orders.size}

다음 글

코틀린[Kotlin] 컬렉션 정리 - 매핑 / 필터링 등(About the Collections in Kotlin - Mapping / Filtering etc..)

 

코틀린[Kotlin] 컬렉션 정리 - 매핑 / 필터링 등(About the Collections in Kotlin - Mapping / Filtering etc..)

https://play.kotlinlang.org/koans/Collections/Introduction/Task.kt Kotlin Playground: Edit, Run, Share Kotlin Code Online play.kotlinlang.org 코틀린 공식문서에 있는 Colletions 파트를 읽으며 정리해보..

soopeach.tistory.com

 

반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기