Uknow's Lab.
article thumbnail

 

 

 

컬렉션과 람다식

코틀린에서 정말 편했던 기능 중 하나인 컬렉션 + 람다식입니다.

자바와 마찬가지로, 코틀린은 배열, 리스트, 집합, Map 등에

sum, avg, sort, max, min, reverse, contain 등 여러 메소드를 지원합니다.

(자료구조와 타입 따라 지원되는 메소드는 조금씩 다릅니다.)

 

그 중, 코틀린에서는 위 메소드들에 람다식을 사용한 여러 편의기능을 제공하는데요.

대표적인 몇 가지의 기능들을 알아보겠습니다.

 

아래 메소드들은 대부분 List, Set, Map등 컬렉션 뿐만 아닌 배열에서도 사용이 가능합니다.

 

 

forEach, forEachIndex

val arr = arrayOf(10, 20, 123, 64, 12)
arr.forEach { println(it) }

// 출력
10
20
123
64
12

 

이미 여러번 나왔던 forEach는 자료구조 내 원소를 하나씩 순회하는 반복문입니다.

 

 

val arr = arrayOf(10, 20, 123, 64, 12)
    arr.forEachIndexed { index, i ->
        println("index: $index, value: $i")
}

// 출력
index: 0, value: 10
index: 1, value: 20
index: 2, value: 123
index: 3, value: 64
index: 4, value: 12

 

forEachIndexd로 자료구조의 인덱스와 값을 함께 순회할 수 있습니다.

 

 

all, any

class Person(val name: String, val age: Int, val height: Int)

fun main() {
    val persons = listOf(
        Person("홍길동", 29, 160),
        Person("전우치", 31, 180),
        Person("사스케", 31, 170)
    )

    println("모두 키가 170 이상인가? ${persons.all { it.height >= 170 }}")
    println("모두 나이가 20 이상인가? ${persons.all { it.age >= 20 }}")
    println("한 명이라도 키가 170 이상인가? ${persons.any { it.height >= 170 }}")
    println("한 명이라도 나이가 40 이상인가? ${persons.any { it.age >= 40 }}")
}

// 출력
모두 키가 170 이상인가? false
모두 나이가 20 이상인가? true
한 명이라도 키가 170 이상인가? true
한 명이라도 나이가 40 이상인가? false

 

all은 데이터가 모두 조건을 만족하는지 검사하는 메소드입니다.

모든 데이터가 조건을 만족해야만 true를 반환하며,

하나라도 틀리면 false를 반환합니다.

 

any는 조건에 만족하는 데이터가 있는지 검사하는 메소드입니다.

하나라도 조건을 만족하는 데이터가 있을 경우 true를 반환합니다.

모든 데이터가 조건을 만족하지 않을 때 false를 반환합니다.

 

위와 같이, 컬렉션 람다식은 객체를 다룰 때 정말 편합니다.

 

 

filter

class Person(val name: String, val age: Int, val height: Int)

fun main() {
    val persons = listOf(
        Person("홍길동", 29, 160),
        Person("전우치", 31, 180),
        Person("사스케", 31, 170)
    )

    val person31 = persons.filter { it.age == 31 }
    person31.forEach { println("${it.name}  ${it.age}") }
}

// 출력
전우치  31
사스케  31



==================================================================



val arr = arrayOf(3, 4, 5, 6, 8, 2, 12, 443, 6576, 75)
arr.filter { it % 2 == 0 }.forEach { println(it) } // 짝수만 뽑아오기

// 출력
4
6
8
2
12
6576

 

filter는 조건에 맞는 원소들만 뽑아올 때 사용하는 메소드입니다.

람다식 안의 조건문이 참이 되는 원소들만 가져와 필터링하며,

 

위 코드는 나이(age)가 31살인 사람만 뽑는데 사용하였습니다.

아래 코드는 배열 내 원소중 짝수(2로 나눴을 때 나머지가 0)만 필터링한 예제입니다.

 

 

count

class Person(val name: String, val age: Int, val height: Int)

fun main() {
    val persons = listOf(
        Person("홍길동", 29, 160),
        Person("전우치", 31, 180),
        Person("사스케", 31, 170)
    )

    val person31 = persons.count { it.age == 31 }
    println(person31)
}

// 출력
2

 

count { } 는 특정 조건에 맞는 원소의 개수를 반환합니다.

위 코드에서는 나이가 31살인 사람만 카운트하였습니다.

 

 

map

val arr = arrayOf(10, 20, 30, 40, 50)
val new = arr.map { it * 2 }

new.forEach { println(it) }

// 출력
20
30
60
80
100

 

map은 forEach와 비슷하게 자료구조 내 원소들을 순회합니다.

다만, map은 반환값이 존재하며,

저는 주로 자료구조 내 값을 가공할 때 쓰곤 합니다.

 

코딩테스트를 할 때 특히나 많이 쓰는 녀석인데,

10 12 13 등으로 입력을 받고, 이걸 숫자형으로 반환받고 싶을 땐,

val arr = readln().split(” “).map{ it.toInt } 로 쓰면 간단히 숫자형 리스트를 받을 수 있습니다.

 

 

first, last

val arr = arrayOf(10, 12, 33, 14, 15, 20)

val firstOdd = arr.first { it % 2 == 1 }
println(firstOdd)

val lastOdd = arr.last { it % 2 == 1 }
println(lastOdd)

// 출력
33
15

 

first / last는 조건에 맞는 첫 번째 / 마지막 원소를 반환하는 메소드입니다.

위 코드에선 각각 첫 번째 홀수, 마지막 홀수를 구하는 용도로 사용하였습니다.

 

 

indexOfFirst, indexOfLast

val arr = arrayOf(10, 12, 33, 14, 15, 20)

val firstOdd = arr.indexOfFirst { it % 2 == 1 }
println(firstOdd)

val lastOdd = arr.indexOfLast { it % 2 == 1 }
println(lastOdd)

// 출력
2
4

 

indexOfFirst / indexOfLast는 first/last와 비슷하게,

조건에 맞는 첫 번째 / 마지막 원소의 인덱스를 반환하는 메소드입니다.

위 코드에선 각각 첫 번째 홀수, 마지막 홀수의 인덱스를 구하는 용도로 사용하였습니다.

 

 

sumOf

val arr = arrayOf(10, 20, 30, 40, 50)

val sum = arr.sumOf { it * 2 }
println(sum)

// 출력
300


===============================================================================


class Person(val name: String, val age: Int, val height: Int)

fun main() {
    val persons = listOf(
        Person("홍길동", 29, 160),
        Person("전우치", 31, 180),
        Person("사스케", 31, 170)
    )

    val ageSum = persons.sumOf { it.age }
    println(ageSum)
}

// 출력
91

 

sumOf는 람다식을 사용해 값들의 합을 구할 때 쓰입니다.

 

위 코드는 각 원소에 * 2씩을 하여 총 합을,

아래 코드는 각 객체의 나이의 합을 구한 코드입니다.

 

 

sortedBy, sortedByDescending

class Person(val name: String, val age: Int, val height: Int)

fun main() {
    val persons = listOf(
        Person("홍길동", 29, 160),
        Person("전우치", 31, 180),
        Person("흥부", 32, 175),
        Person("놀부", 33, 175),
        Person("사스케", 34, 170),
        Person("나루토", 35, 175),
    )

    persons.sortedBy { it.age }.forEach { println("${it.name} ${it.age} ${it.height}") }
}


// 출력
홍길동 29 160
전우치 31 180
흥부 32 175
놀부 33 175
사스케 34 170
나루토 35 175



=======================================================================



fun main() {
    val nums = arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18)
    nums.sortedByDescending { it % 3 }.forEach { println(it) }
}

// 출력
2
5
8
11
14
17
1
4
7
10
13
16
3
6
9
12
15
18

 

sortedBy는 일반적인 sort 메소드에 람다식을 사용할 수 있게 해줍니다.

위 코드는 나이(age)를 기준으로 정렬을 한 코드입니다.

아래 코드는 각 원소를 3으로 나눈 것을 기준으로 내림차순 정렬한 코드입니다.

 

sortedBy는 기본적으로 오름차순이며,

내림차순으로 하고 싶을 sortedByDescending을 사용하면 됩니다.

 

 

 

이 외에도 코틀린의 컬렉션은 다양한 기능을 지원합니다.

자세한 내용은 코틀린 공식 문서를 참고해주세요.

 

https://kotlinlang.org/docs/home.html

 

Kotlin Docs | Kotlin

 

kotlinlang.org

 

profile

Uknow's Lab.

@유노 Uknow

인생은 Byte와 Double 사이 Char다. 아무말이나 해봤습니다.