PS문제를 하나씩 풀다보니 공부가 필요한 문법에 대해서 정리한 글입니다.
코틀린에는 자료 구조를 편하게 다루기 위해 제공되는 라이브러리인 컬렉션이 있고
컬렉션 내에는 데이터를 모아주는 함수인reduce,fold가 있습니다.
오늘은 이 두 개를 알아볼까 합니다.
reduce를 번역하면 줄이다 라는 뜻을 가지고 있습니다.
inline fun <S, T : S> Iterable<T>.reduce(operation: (acc: S, T) -> S): S
첫 번째 요소부터 시작하여 값을 누적하고 현재 누적값과
각 요소에 왼쪽에서 오른쪽으로 연산을 적용합니다.
컬렉션이 비었다면 예외 처리가 동작합니다.위에서 확인 할 수 있듯 reduce 연산을 수행 시 각 값들은 reduce에서 받은 operation 함수에
해당하는 연산이 재귀적으로 수행되어 반환합니다.
만약 1부터 10까지의 합을 구하는 프로그램을 작성한다고 하면
reduce를 사용하면 더욱 가독성 좋게 사용할 수 있습니다.여기서 알 수 있는 점은 reduce는 초기 값을 첫 번째 요소로 정하고
두 번째 요소부터 연산을 진행합니다.또한 순차적으로 연산을 수행하며 맨 마지막으로 계산된 값을 반환합니다.
fun main(){
val ans = (1..10).toList()
//for문
var result = 0
for(x in ans){
result += x
}
println("1부터 10까지의 총합 : $result") //55
//reduce 함수 사용
val reduce = ans.reduce {total, num ->
total + num
}
println("1부터 10까지의 총합 : $reduce") //55
}
1. 초기 값 1(total) + 다음 원소 2(num)를 더한 값이 reduce에 저장된다.
2. reduce 안에 있는 2이 total안에 들어가고 다음 인자 3(num)이 더해져 다시 reduce 안에 저장된다.
3. 이를 반복하여 인자가 10까지 더해진다.
reduce에서는 비어있는 컬렉션이라면 예외처리를 동작하지만
fold는 이런 비어있는 컬렉션의 초기 값을 정해주어 사용합니다.
inline fun <T, R> Iterable<T>.fold(initial: R, operation: (acc: R, T) -> R): R
초기 값부터 시작하여 값을 누적하고
현재 누적값과 각 요소에 왼쪽에서 오른쪽으로 연산을 적용합니다.
컬렉션이 비어 있는 경우 지정된 초기 값을 반환합니다.
똑같이 1부터 10까지의 합을 구하는 함수인데
이번에는 2부터 10까지의 배열을 주었지만
fold함수로 초기 값을 1로 지정해 주었을 때 똑같이 55를 출력하는 것을 알 수 있습니다.
fun main(){
//fold 함수
val arr = (2..10).toList()
val fold = arr.fold(1) { total, num ->
total + num
}
println("1부터 10까지의 총합 : $fold") //55
}
공식문서의 설명대로 초기 값을 반환합니다.
fun main(){
//fold 비어있는 컬렉션
val emptyList = emptyList<Int>()
val emptyFold = emptyList.fold(1){ total, num ->
total + num
}
println("emptyFold : $emptyFold") // 1
}
reduce와fold는collection을 누적하여 계산해주는 함수이다.
reduce는 비어 있는 컬렉션에 대해 예외처리를 하지만
fold는 초기 값을 정해주면 비어있는 컬렉션에 대해 fold 함수를 사용해도
초기 값을 출력한다.