본문 바로가기

LANGUAGES, METHODLOGY/Kotlin

[Kotlin] 컬렉션 함수형 API로 컬렉션 쉽게 갖고 놀기

개발을 하다 보면 리스트형 변수와 필연적으로 마주하게 되는데, 단순히 이런 컬렉션 객체를 사용하는 것에서 넘어

 

특정한 조건에 따라 필터링을 한 목록을 얻는다던지, 검색한 모든 결과값에서 원하는 결과가 있는지 확인한다던지 하는 요구사항을 필요로 한 적이 있을 것이다.

 

코틀린을 사용할 때, 이러한 요구사항을 손쉽게 충족해주는 API를 정리해보고자 한다!

 

컬렉션 함수형 API

우선 Kotlin in Action에서 소개하는 함수 중 필수적인 함수로 소개하는 filter와 map에 대해 살펴보자.

filter

filter를 사용하는 경우, 호출하는 대상 컬렉션으로부터 필요한 조건을 filter 코드 블럭에 선언하면 조건에 맞는 List로 이를 반환하게 된다.

 

val targetList = listOf("윤철수", "최영희", "최승환", "산다라박")

fun filterListAndPrint() {
	targetList.filter { it.startsWith("최", false) }
    .forEach {
    	println(it)
    }
}

// Result
// "최영희"
// "최승환"

 

map

map을 사용하면 호출하는 대상 컬렉션의 원소를 재가공(Mapping)해 반환한다. 

val targetList = listOf(1, 5, 10, 20)

fun mapListAndPrint() {
	targetList.map { it * 2 }
    .forEach {
    	println(it)
    }
}

// Result
// 2
// 10
// 20
// 40

 

여기까지는 간단하게 사용하기 쉬운 함수들이라 보면 되겠다.

all 

선언한 술어 함수 조건에 호출하는 대상 컬렉션이 모두 충족되는지를 확인한다.

술어 함수에 대한 조건을 필요에 따라 선언해 활용해 볼 수 있기 때문에, 확장성과 재사용성이 뛰어난 함수라 보면 되겠다.

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

val targetList = listOf(Person(30, "윤철수"), Person(31, "최승환"), Person(25, "최영희"), Person(35, "산다라박"))
val isUnderThirty = { p: Person -> p.age < 30 }

fun isAllUnderThirty() {
	print(targetList.all(isUnderThirty))
}

isAllUnderThirty()

// Result
// false

any

선언한 술어 함수 조건에 호출하는 대상 컬렉션의 원소중 단 하나라도 충족이 되는지 확인한다.

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

val targetList = listOf(Person(30, "윤철수"), Person(31, "최승환"), Person(25, "최영희"), Person(35, "산다라박"))
val underThirtyExists = { p: Person -> p.age < 30 }

fun isAllUnderThirty() {
	print(targetList.any(underThirtyExists))
}

isAllUnderThirty()

// Result
// true

count

선언한 술어 함수 조건에 맞는 호출 컬렉션의 원소 갯수를 확인한다.

이를 사용하지 않고 filter를 사용한 list의 size를 이용하는 경우, filter가 된 list가 새롭게 반환되기 때문에 

count를 사용하게 되면 새로운 컬렉션 생성 없이 호출 대상의 원소 갯수를 확인할 수 있다는 장점이 있다!

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

val targetList = listOf(Person(30, "윤철수"), Person(31, "최승환"), Person(25, "최영희"), Person(35, "산다라박"))
val underThirtyExists = { p: Person -> p.age < 30 }

fun isAllUnderThirty() {
	print(targetList.count(underThirtyExists))
}

isAllUnderThirty()

// Result
// 1

 

find

선언한 술어 함수 조건에 맞는 원소 1개를 반환한다. 조건에 충족하는 원소가 없는 경우 null을 return 하게 된다!

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

val targetList = listOf(Person(30, "윤철수"), Person(31, "최승환"), Person(25, "최영희"), Person(35, "산다라박"))
val underThirtyExists = { p: Person -> p.age < 30 }

fun isAllUnderThirty() {
	print(targetList.find(underThirtyExists))
}

isAllUnderThirty()

// Result
// Person(age=25, name=최영희)


groupBy

선언한 컬렉션에서 특정 조건에 따라 구분된 컬렉션의 집합을 반환한다.

손이 많이 갈 작업을 손쉽게 처리해주는 고마운 API 라고 봐야겠다 :)


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

val targetList = listOf(Person(30, "윤철수"), Person(30, "최승환"), Person(25, "최영희"), Person(35, "산다라박"))

fun groupByAge() {
	print(targetList.groupBy( it.age ))
}

groupByAge()

// Result
// {30=[Person(age=30, name=윤철수), Person(age=30, name=최승환)], 25=[Person(age=25, name=최영희)], 35=[Person(age=35, name=산다라박)]}

 

본 포스트는 Kotlin in Action을 참조해 작성하였습니다. 

 

Kotlin in Action

코틀린이 안드로이드 공식 언어가 되면서 관심이 커졌다. 이 책은 코틀린 언어를 개발한 젯브레인의 코틀린 컴파일러 개발자들이 직접 쓴 일종의 공식 서적이라 할 수 있다. 코틀린 언어의 가장

book.naver.com