# 람다 활용법 In Collection
- Collection 사용 시 람다를 유용하게 쓸 수 있는 경우가 많다
Collection - filter 함수
단어그대로 리스트 원소 중 원하는 원소만 filtering 하겠다는 뜻
리스트의 각 원소를 람다에 넘겨서 람다의 return 값이 true인 원소로 이루어진 리스트를 새로 반환한다
고로, 람다의 마지막 줄은 TRUE/FALSE를 리턴해야 한다
//filter 예제 (1)
val listInt = listOf(1, 2, 3, 4)
listInt.filter { it % 2 == 0 } // [2,4]
//filter 예제 (2)
val listStudents = listOf(Student("Tina", 4), Student("Scott", 1))
listStudents.filter { it.grade >= 4 } //[Student(name=Tina, grade=4)]
Collection - map 함수
리스트 원소의 값을 수정해서 새로 만들어서 반환 한다
람다의 마지막 줄은 새로 만들어질 값을 리턴해야 한다
//map 예제 (1)
val listInt = listOf(1, 2, 3, 4)
println(listInt.map { it + 1 }) // [2, 3, 4, 5]
println(listInt.map {
it * 100
it + 1
}) // [2, 3, 4, 5] - 'it*100'은 새로 만들어지는 list 와 무관함을 볼 수 있다
println(listInt.map { it % 2 == 0 }) // [false, true, false, true]
//map 예제 (2)
val listStudents = listOf(Student("Tina", 4), Student("Scott", 1))
println(listStudents.map { it.name }) //[Tina, Scott] - 'name'으로만 이루어진 새 list를 얻을 수 있다
println(listStudents.map { it.grade }) //[4, 1] - 'grade'로만 이루어진 새 list를 얻을 수 있다
ex) grade가 가장 높은 학생 이름 구하기
val listStudents = listOf(Student("Tina", 4), Student("Scott", 1))
istStudents.filter { it.grade == listStudents.maxByOrNull(Student::grade)!!.grade} //[Tina]
위 식은 Collectin 사용 시 람다안에 람다를 쓴 경우인데, 동작을 알아보기 위해 아래와 같이 print를 추가해 보자
println(listStudents.filter {
println("filter")
it.grade == listStudents.maxByOrNull { it ->
println("maxByOrNull")
it.grade
}!!.grade
})
[결과]
// filter
// maxByOrNull
// maxByOrNull
// filter
// maxByOrNull
// maxByOrNull
원소 2개 짜리 리스트로 실행했을 뿐인데도, 수행 복잡도가 올라가는 것을 볼 수 있다
그러므로, Collection에서의 람다 중첩은 조심해서 쓰도록 하자
위의 식을 그나마 효율적이게 만들어보면
val maxGrade = listStudents.maxByOrNull { it -> it.grade }!!.grade
listStudents.filter { it.grade == maxGrade }
print 해 보면
val maxGrade = listStudents.maxByOrNull { it ->
println("maxByOrNull")
it.grade}!!.grade
listStudents.filter {
println("filter")
it.grade == maxGrade
}
[결과]
// maxByOrNull
// maxByOrNull
// filter
// filter
수행 횟수가 줄어드는 것 을 볼 수 있다
*map의 경우에서 key와, value에 대해 각각의 filter/map 함수가 있다
filterKeys, mapKeys, filterValues, mapValues
Collection - 원소 조건 판별
all / any / count / find
all : 모든 원소가 조건을 만족하는지 TRUE/FALSE 반환
any : 적어도 1개의 원소가 조건을 만족하는지 TRUE/FALSE 반환
count : 조건을 만족하는 원소 갯수 반환
find : 조건을 만족하는 가장 첫번째 원소를 반환
data class Student constructor(val name: String, val grade: Int)
val isGrade4 = { student: Student -> student.grade == 4 }
val isGrade5 = { student: Student -> student.grade == 5 }
val students = listOf(Student("Tina", 4), Student("Scott", 1), Student("July", 4))
//조건의 만족에 대한 Boolean 갑을 반환
println(students.all(isGrade4)) //false
println(students.any(isGrade4)) //true
println(students.count(isGrade4)) //2
//조건을 만족하는 가장 첫번째 원소를 반환한다. 없을 경우 null.
println(students.find(isGrade4)) // Student(name=Tina, grade=4)
println(students.find(isGrade5)) // null
Collection - 분류
groupBy : 특성/조건이 동일한 원소들을 group지어 반환한다
리턴 형태 =
Map<K, List<T>>
Map<동일 특성, 원소 List>
println(students.groupBy { it.grade })
//{4=[Student(name=Tina, grade=4), Student(name=July, grade=4)], 1=[Student(name=Scott, grade=1)]}
println(students.groupBy(isGrade4))
//{true=[Student(name=Tina, grade=4), Student(name=July, grade=4)], false=[Student(name=Scott, grade=1)]}
Collection - 리스트의 리스트 원소들을 한데 모아 보고 싶을 때 (list of list)
flatten/flatMap
flatten() : 리스트 안의 원소가 리스트 일 때, 원소 리스트 들을 값을 한 데 모아서 List로 반환한다
flatMap{} : flatten과 동일 하지만 원소 리스트의 값을 변경해서 반환하고 싶을 경우 사용한다
val strings = listOf("abc".toList(), "cde".toList())
// [[a, b, c], [c, d, e]]
// (1)그냥 펼쳐보이기
println("flatten() = " + strings.flatten())
// [결과] flatten() = [a, b, c, c, d, e]
1) [a, b, c].map{ ~ } => [A,B,C]
// (2)대문자 변경 후 펼쳐보이기 2) [c, d, e].map{ ~ } => [C,D,E]
println("flatMap() = " + strings.flatMap { charList -> charList.map { char -> char.uppercase() } })
// [결과] flatMap() = [A, B, C, C, D, E]
출처 : Kotlin In Action - 에이콘 출판사
(위 도서를 학습하고 개인 학습용으로 정리한 내용입니다)
'Kotlin' 카테고리의 다른 글
[Kotlin] 4.람다 - 함수형 인터페이스(SAM 인터페이스) (0) | 2021.12.04 |
---|---|
[Kotlin] 4.람다 In Collection(Sequence) (0) | 2021.11.17 |
[Kotlin] 4.람다 - 기본 (0) | 2021.11.15 |
[Kotlin] 3. Object (0) | 2021.11.15 |
[Kotlin] 3. Data Class, by (0) | 2021.11.07 |