Kotlin

[Kotlin]FoldRight && Fold

onemask 2019. 12. 27. 00:37

Kotlin의 FoldRight와 Fold 함수에 대하여 알아보자. 

  • 위 두 함수는 모두 Collection이나 List에서 사용이 가능하다. 

 

 # FoldRight 

사용 예제를 알아보기 앞서 FoldRight 원형을 살펴보자.

IntellIj 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의 원형은 아래와 같다. 

IntellIJ 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

IntellIj 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의 원형은 아래와 같다.

IntellIJ foldIndexed

 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/

 

How to use fold, foldIndexed, foldRight and foldRightIndexed in Kotlin - Code vs Color

How to use fold, foldIndexed, foldRight and foldRightIndexed in Kotlin : If you want to do certain operation on the elements of a list serially, you can use fold(). This method takes one initial value Read more…

www.codevscolor.com

https://gold.gitbook.io/kotlin/collections/aggregate-operations/fold-vs-foldright

 

fold vs foldRight

 

gold.gitbook.io

 

LIST