2017-10-20 35 views
3

Kotlin有没有在已过滤的数字列表上进行sum()操作的方法,但实际上并未首先过滤出元素?总结列表中的数字的一个子集

我正在寻找这样的事情:

val nums = listOf<Long>(-2, -1, 1, 2, 3, 4) 
val sum = nums.sum(it > 0) 

回答

4

您可以使用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 
} 

你可以通过一个函数,其中函数转换负值为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 

如果你需要一个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 
} 

然后,toInt()转换可以带走。

nums.sumByLong { if (it > 0) it else 0 } 

如@Ruckus T-臂架建议,if (it > 0) it else 0可以使用Long.coerceAtLeast()它返回该值本身,或者给定的最小值被简化了:

nums.sumByLong { it.coerceAtLeast(0) } 
+2

可以使用'it.coerceAtLeast(0)'而不是“if(it> 0)else else” –

相关问题