Kotlin/Kotlin

Kotlin fold, reduce 메서드

Junuuu 2024. 3. 10. 00:01

Reduce 메서드

public inline fun <S, T : S> Iterable<T>.reduce(operation: (acc: S, T) -> S): S {
    val iterator = this.iterator()
    if (!iterator.hasNext()) throw UnsupportedOperationException("Empty collection can't be reduced.")
    var accumulator: S = iterator.next()
    while (iterator.hasNext()) {
        accumulator = operation(accumulator, iterator.next())
    }
    return accumulator
}

reduce 메서드의 경우 Iterable의 확장함수입니다.

초기값은 컬렉션의 첫 번째 요소이며 컬렉션을 순회하면서 operation을 지속적으로 수행합니다.

 

해당 컬렉션이 비어있으면 예외가 발생한다는 특징이 있습니다.

따라서 컬렉션이 비어있을 수 있다면 reduceOrNull을 활용하면 null을 반환하게 됩니다.

 

Reduce 메서드 실습

    @Test
    fun `reduce를 학습해보자`(){
        val numbers = (1..10).toList()

        val sumUsingReduce = numbers.reduce {total, num ->
            total + num
        }
        println(sumUsingReduce) // 55


        val emptyList = emptyList<Long>()

        val emptyResult = emptyList.reduceOrNull{ total, num ->
            total + num
        }

        println(emptyResult) //null

        // java.lang.UnsupportedOperationException: Empty collection can't be reduced.
        emptyList.reduce{ total, num ->
            total + num
        }
    }

 

1부터 10까지의 정수가 담긴 List의 누적합을 더할 때 List의 첫 번째 요소를 초기값으로 활용합니다.

또한 reduceOrNull은 리스트가 비어있는경우 null을 반환하고 reduce를 사용한 경우에는 예외가 발생하게 됩니다.

 

 

Fold 메서드

public inline fun <T, R> Iterable<T>.fold(initial: R, operation: (acc: R, T) -> R): R {
    var accumulator = initial
    for (element in this) accumulator = operation(accumulator, element)
    return accumulator
}

fold 메서드도 Iterable의 확장함수입니다.

초기값부터 시작하여 처음부터 끝까지 연산을 적용하여 값을 누적합니다.

컬렉션이 비어 있으면 지정된 초기 반환값을 반환합니다.

 

Fold 메서드 실습

    @Test
    fun `fold를 학습해보자`(){
        val numbers = (1..10).toList()
        // total의 초기값은 100으로 시작한다.
        // fold는 초기값을 지정할 수 있다!!
        val sumUsingFold = numbers.fold(100) { total, num ->
            total + num
        }
        println(sumUsingFold) // 155

        val emptyList = emptyList<Int>()

        val emptyUsingFold = emptyList.fold(10){ total, num ->
            total + num
        }

        println(emptyUsingFold) // 10

    }

1부터 10까지의 정수가 담긴 List의 누적합을 더할 때 초기값을 100으로 주면 155라는 결과가 나오게 됩니다.

또한 fold는 reduce와 다르게 리스트가 비어있는경우 초기값을 반환하게 됩니다.