[Kotlin] 컬렉션 함수(FD)

이상목·2024년 4월 22일
0

Kotlin

목록 보기
4/20

컬렉션 함수

  • 컬렉션의 요소들을 순회할 때 for 문을 쓰면 편리하지만, 함수형 프로그래밍을 지향하는 코틀린은 컬렉션을 다룰 때 필요한 여러 가지 유용한 함수들을 지원한다.
  • 컬렉션 함수는 list나 set, map, 또는 배열 (array) 에 일반 함수 또는 람다 함수 형태를 사용하여 for 문 없이도 아이템을 순회하며 참조하거나 조건을 걸고, 구조의 변경까지 가능한 여러 함수를 지칭한다.

1. forEach 구문

  • 아래 예시와 같이 사용하며, it이라는 키워드로 각각의 요소에 대응하여 안에 들어있는 함수를 실행한다.
fun main() {
    var a: List<Int> = listOf(1, 2, 3)
    
    a.forEach {
        println(it + 1)
    }
}

출력

2
3
4



2. filter

  • 조건에 맞는 요소만 컬렉션으로 다시 묶어 반환해주는 함수이다. 다음과 같이 사용한다.
fun main() {
    var a: List<Int> = listOf(1, 2, 3)
    
    var b = a.filter {
        it > 1
    }
    
    println(b)
}

출력

[2, 3]



3. map

  • 각각의 요소에 수식 또는 함수들을 적용한 컬렉션을 반환한다. 다음과 같이 사용할 수 있다.
fun main() {
    var a: List<Int> = listOf(1, 2, 3)
    
    var b = a.map {
        it * 2
    }
    
    println(b)
}

출력

[2, 4, 6]



4. any, all, none

  • 모두 boolean을 반환하는 함수로, 요소를 모두 검사하여 해당 조건에 맞으면 true/false를 반환하는 함수이다. 다음과 같이 사용한다.
fun main() {
    var a: List<Int> = listOf(1, 2, 3)
    
    if (a.any{ it==2 }) {
        println("any: 하나라도 조건에 맞으면 true를 반환")
    }
    
    if (a.all{ it is Int }) {
        println("all: 모두 조건에 맞으면 true를 반환")
    }
    
    if (a.none{ it > 4 }) {
        println("none: 하나도 조건에 맞지 않으면 true를 반환")
    }
}

출력

any: 하나라도 조건에 맞으면 true를 반환
all: 모두 조건에 맞으면 true를 반환
none: 하나도 조건에 맞지 않으면 true를 반환



5. first, last, find, findLast, firstOrNull, lastOrNull

  • first는 두 가지 방법으로 쓸 수 있는데, 함수 형태로 사용을 하면 첫 번째 아이템을 반환하지만, 중괄호 ({, })에 넣은 채로 조건을 넣어 사용하면 조건에 맞는 첫 번째 아이템을 반환하게 된다.
  • last도 first와 같은 기능을 하지만 반대 순서부터 진행 (마지막에서 가장 가까운) 한다는 점이 다르다.
fun main() {
    var a: List<Int> = listOf(1, 2, 3, 4)
    
    println(a.first())
    println(a.first{ it > 1 })
    
    println(a.last())
    println(a.last{ it < 4 })
}

출력

1
2
4
3

  • first와 last는 각각 find와 findLast 함수로 대체될 수 있다.
  • first와 last를 사용할 때에는 주의할 점이 있는데, 만약 해당 조건에 맞는 아이템이 없을 경우, NoSuchElementException 예외가 일어난다는 점이다.
  • 이 때에는 firstOrNull 또는 lastOrNull 함수를 사용하면 해당하는 아이템이 없을 경우에 null을 반환해준다.



6. count

  • 일반 함수로 사용 시에는 해당 컬렉션의 아이템 개수를 반환한다.
  • 그러나 중괄호를 걸고 조건을 안에 넣어주면, 조건에 맞는 아이템의 개수를 반환하게 된다.
fun main() {
    var a: List<Int> = listOf(1, 2, 3, 4)
    
    println(a.count())
    println(a.count{ it > 2 })
}

출력

4
2



7. associateBy

  • 아이템에서 key를 뽑아내어 map으로 만드는 함수이다.
  • 컬렉션에 있는 객체들의 특정한 속성을 key로 삼은 map을 만들고 싶을 때 사용할 수 있다.
fun main() {
    var people: List<Person> = listOf(Person("sang", 24),
                                      Person("mok", 12),
                                      Person("lee", 36))
    var map = people.associateBy{ it.name }
    
    println(map)
}

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

출력

{sang=Person@6b884d57, mok=Person@38af3868, lee=Person@77459877}

  • 보면 각각의 Person 객체 (이미 존재하던 객체) 가 지정한 속성을 key로 갖는 map의 value로 들어간 것을 볼 수 있다.



8. groupBy

  • key를 기준으로 그룹을 만들어 해당 값을 가진 객체끼리 묶은 배열을 value로 갖는 map을 반환하는 함수이다.
fun main() {
    var people: List<Person> = listOf(Person("sang", 12),
                                      Person("mok", 12),
                                      Person("lee", 36))
    var map = people.groupBy{ it.age }
    
    println(map)
}

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

출력

{12=[Person@2a84aee7, Person@a09ee92], 36=[Person@30f39991]}

  • age가 12인 객체끼리 묶인 list가 12라는 key의 value로 지정된 것을 볼 수 있다.



9. partition

  • 아이템에 조건을 걸어 true인지 false인지에 따라 두 컬렉션으로 나누어 주는 함수이다.
  • 두 컬렉션이 따로 반환되는 것이 아닌 Pair라는 클래스의 객체로 반환되므로 각각의 컬렉션을 first, second로 참조하여 사용하면 된다.
fun main() {
    var people: List<Person> = listOf(Person("sang", 12),
                                      Person("mok", 24),
                                      Person("lee", 36))
    var pair = people.partition{ it.age > 20 }
    
    println("first: ${pair.first}")
    println("second: ${pair.second}")
}

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

출력

first: [Person@30f39991, Person@452b3a41]
second: [Person@23fc625e]

  • 또는 변수 각각에 다음과 같이 넣을 수도 있다.
fun main() {
    var people: List<Person> = listOf(Person("sang", 12),
                                      Person("mok", 24),
                                      Person("lee", 36))
    var (ageOver20, ageUnder20) = people.partition{ it.age > 20 }
    
    println(ageOver20)
    println(ageUnder20)
}

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

출력

[Person@30f39991, Person@452b3a41][Person@23fc625e]



10. flatMap

  • 아이템마다 원하는 컬렉션을 만들어 만들어진 컬렉션들을 합쳐서 (flat하게) 반환하는 함수이다. 다음과 같이 사용한다.
fun main() {
    var nums: List<Int> = listOf(1, 3, 5)
    
    var flat = nums.flatMap {
        listOf(it * 2, it + 6)
    }
    
    println(flat)
}

출력

[2, 7, 6, 9, 10, 11]

  • 위의 예시를 보면, 첫 번째 아이템인 1에 있어 flatMap에서 만들어진 리스트는 [2, 7]일 것이다.
  • 두 번째 아이템인 3에 있어 만들어진 리스트는 [6, 9], 그리고 5에 있어서는 [10, 11] 이다.
  • 따라서 이 모든 리스트들을 flat하게 하나의 컬렉션으로 합쳤으므로 결과는 [2, 7, 6, 9, 10, 11]이 된다.



11. getOrElse

  • 이는 컬렉션에서 소괄호 안의 index에 해당하는 아이템이 존재할 경우, 해당 아이템을 반환하고, 존재하지 않을 경우 중괄호 안의 값을 반환하는 함수이다
fun main() {
    var nums: List<Int> = listOf(1, 3, 5)
    
    println(nums.getOrElse(2) { 10 }) // nums[2] 가 존재하므로 5 반환
    println(nums.getOrElse(5) { 10 }) // nums[5] 가 없으므로 10 반환
}

출력

5
10



12. zip

  • 파이썬의 zip과 비슷한 기능을 하는 함수이다.
  • 두 개의 컬렉션 사이에 zip이라는 키워드를 넣어 사용하며, 두 컬렉션에 포함된 아이템들을 1:1로 매칭시켜 Pair 객체를 만들어 List에 넣어 반환하는 함수이다.
  • 이 때, 두 컬렉션의 크기가 맞지 않을 경우, 더 작은 컬렉션의 개수만큼의 Pair 객체 아이템이 들어간 List를 만들어 반환하게 된다.
fun main() {
    var nums: List<Int> = listOf(1, 3, 5)
    var strings: List<String> = listOf("one", "three", "five", "seven")
    
    for ((num, string) in nums zip strings) {
        println("${num}: ${string}")
    }
}

출력

1: one
3: three
5: five

profile
기록은 기억을 지배한다.

0개의 댓글