对列表中的数字的子集求和

Nat*_*son 11 kotlin

在Kotlin中有没有办法在过滤的数字列表sum()上进行操作,而不是先实际过滤出元素?

我正在寻找这样的东西:

val nums = listOf<Long>(-2, -1, 1, 2, 3, 4)
val sum = nums.sum(it > 0)
Run Code Online (Sandbox Code Playgroud)

Bak*_*aii 12

你可以利用Iterable<T>.sumBy:

/**
 * Returns the sum of all values produced by [selector] function applied to each element in the collection.
 */
public inline fun <T> Iterable<T>.sumBy(selector: (T) -> Int): Int {
    var sum: Int = 0
    for (element in this) {
        sum += selector(element)
    }
    return sum
}
Run Code Online (Sandbox Code Playgroud)

您可以将函数传递给函数,函数将负值转换为0.因此,它将列表中所有大于0的值相加,因为添加0对结果没有影响.

val nums = listOf<Long>(-2, -1, 1, 2, 3, 4)
val sum = nums.sumBy { if (it > 0) it.toInt() else 0 }
println(sum)    //10
Run Code Online (Sandbox Code Playgroud)

如果您需要Long值回来了,你有编写扩展Long就像Iterable<T>.sumByDouble.

inline fun <T> Iterable<T>.sumByLong(selector: (T) -> Long): Long {
    var sum: Long = 0
    for (element in this) {
        sum += selector(element)
    }
    return sum
}
Run Code Online (Sandbox Code Playgroud)

然后,toInt()转换可以被取消.

 nums.sumByLong { if (it > 0) it else 0 }
Run Code Online (Sandbox Code Playgroud)

正如@Ruckus T-Boom所建议的,if (it > 0) it else 0可以简化使用Long.coerceAtLeast()返回值本身或给定的最小值:

nums.sumByLong { it.coerceAtLeast(0) }
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用`it.coerceAtLeast(0)`而不是`if(it> 0)it else 0` (5认同)