[Kotlin]FoldRight && Fold
Kotlin의 FoldRight와 Fold 함수에 대하여 알아보자.
- 위 두 함수는 모두 Collection이나 List에서 사용이 가능하다.
# FoldRight
사용 예제를 알아보기 앞서 FoldRight 원형을 살펴보자.
주석에 아주 친절하게 나와 있다.
initial로 선언한 초기값에서 시작하며 operation을 적용하는데,
오른쪽에서 -> 왼쪽으로 진행된다는 뜻이다.
//FoldRight
val list = listOf(1, 2, 3, 4, 5)
val sumTotal = list.foldRight(list.first(), { next, total ->
println("next $next total $total")
next + total
})
println("sumTotal $sumTotal")
/** Region of Print
next 5 total 1
next 4 total 6
next 3 total 10
next 2 total 13
next 1 total 15
sumTotal 16 */
print로 변수의 값을 확인해보자.
초기 total로 선언된 값 list.first() 즉 1이고, next는 가장 오른 쪽에 있는 5 임을 알 수 있다.
그렇게 오른쪽에서 왼쪽으로 operator로 선언한 동작을 실행하는 것이
fold Right 임을 알 수 있다.
# Fold
Fold의 원형은 아래와 같다.
FoldRight와 유사하며 동일하고 방향만 왼쪽에서 -> 오른쪽으로 operation이 적용된다는 점이 다르다.
//Fold
val list = listOf(1, 2, 3, 4, 5)
val sumLeftTotal = list.fold(list.first(), { next, total ->
println("next $next total $total")
total + next
})
println("sum LeftTotal $sumLeftTotal")
/** Region of Print
next 1 total 1
next 2 total 2
next 4 total 3
next 7 total 4
next 11 total 5
sum LeftTotal 16 */
가장 첫 번째 있는 total 값이 1 그 이후로 왼쪽에 있는 값이 next로 그 둘을 더 해준다.
# FoldRightIndex
FoldRight와 유사하고 접근할 수 있는 index가 operation에 추가되었다.
예문을 살펴보자.
Object List도 가능할까 테스트해봤는데 가능하다.
data class Fruit(
val price: Int,
val name: String
)
val objectList =listOf(
Fruit(100, "apple"),
Fruit(200, "pineapple"),
Fruit(500, "watermelon")
)
val fruitList = objectList.foldRightIndexed(0, { index, fruitPrice, total ->
println("\n index $index fruitPrice $fruitPrice total $total ")
fruitPrice.price + total
})
println("fruitList $fruitList")
/** Region of Print
index 2 fruitPrice Fruit(price=500, name=watermelon) total 0
index 1 fruitPrice Fruit(price=200, name=pineapple) total 500
index 0 fruitPrice Fruit(price=100, name=apple) total 700
fruitList 800 */
Fruit이라는 data class를 생성해주고 objectList로 여러 개의 Fruit를 넣어준다.
print 된 값들을 살펴보면 위와 같다.
foldRight 이기 때문에 가장 오른쪽에 있는 index로 접근되고 초기 선언된 값 0이 total 값으로 선언되었다.
그렇게 선언된 operation에 따라 objectList의 오른쪽에서 왼쪽으로 total 값에 Fruit.price를 더해준다.
# FoldIndex
foldIndex의 원형은 아래와 같다.
val fruitLeftList = objectLlist.foldIndexed(objectList.first().name, { index, fruitName, total ->
println("\n index $index fruitName $fruitName total $total ")
fruitName + " " + next.name
})
println("fruitLeftList $fruitLeftList")
/** Region of Print
index 0 fruitName apple total Fruit(price=100, name=apple)
index 1 fruitName apple apple total Fruit(price=200, name=pineapple)
index 2 fruitName apple apple pineapple total Fruit(price=500, name=watermelon)
fruitLeftList apple apple pineapple watermelon */
objectList는 위와 동일한 FruitList를 사용한다고 했을 때 출력되는 print 값은 위와 같다.
objectList의 첫 번째 이름인 apple이 fruitName의 초기값으로 설정되었다.
그렇게 fruitName과 왼쪽 objectList의 name부터 하나씩 더해간다.
REf)
https://www.codevscolor.com/kotlin-fold-foldindexed-foldright-foldrightindexed/
https://gold.gitbook.io/kotlin/collections/aggregate-operations/fold-vs-foldright