drcarter의 DevLog

val items = listOf(1, 2, 3, 4, 5)
// actual sum of 15

이와 같은 collection에서 전체 합을 구해보기.

 

1. foreach

@Test
fun sumTest_1() {
    var total = 0
    items.forEach {
        total += it
    }
    Assert.assertEquals(total, actual)
}
/**
 * Performs the given [action] on each element.
 */
@kotlin.internal.HidesMembers
public inline fun <T> Iterable<T>.forEach(action: (T) -> Unit): Unit {
    for (element in this) action(element)
}

 

가장 무난하게 많이??이들 사용했을것 같은 부분.

 

 

2. sum()

@Test
fun sumTest_2() {
    val total = items.sum()
    Assert.assertEquals(total, actual)
}
/**
 * Returns the sum of all elements in the collection.
 */
@kotlin.jvm.JvmName("sumOfInt")
public fun Iterable<Int>.sum(): Int {
    var sum: Int = 0
    for (element in this) {
        sum += element
    }
    return sum
}

각 element들의 합계를 바로 구한다. foreach의 내용이 바로 sum의 내용과 같음.

 

 

3. reduce

@Test
fun sumTest_3() {
    val total = items.reduce { acc, i -> acc + i }
    Assert.assertEquals(total, actual)
}
/**
 * Accumulates value starting with the first element and applying [operation] from left to right to current accumulator value and each element.
 * 
 * @sample samples.collections.Collections.Aggregates.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
}

첫번째 element가 기본값으로 operation의 block내용을 가져와서 합계를 구함. 

 

 

4. fold

@Test
fun sumTest_4() {
    val total = items.fold(0) { acc, i ->
        acc + i
    }
    Assert.assertEquals(total, actual)
}
/**
 * Accumulates value starting with [initial] value and applying [operation] from left to right to current accumulator value and each element.
 */
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
}

reduce와의 차이는 초기값을 지정할 수 있음.