对列表中的数字子集求和



Kotlin 中有没有办法对过滤的数字列表进行sum()操作,而无需先过滤掉元素?

我正在寻找这样的东西:

val nums = listOf<Long>(-2, -1, 1, 2, 3, 4)
val sum = nums.sum(it > 0)
您可以使用

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值,则必须像Iterable<T>.sumByDouble一样为Long编写扩展。

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-Boom 所建议的,可以使用返回值本身或给定最小值的Long.coerceAtLeast()来简化if (it > 0) it else 0

nums.sumByLong { it.coerceAtLeast(0) }

sumBy 和 sumByDouble 是从 kotlin 1.5 Deprecated。您可以查看这些链接。

使用 sumOf 获取ListArray的总和

sumOf

返回应用于集合或 Array 中每个元素的选择器函数生成的所有值的总和。

例:

data class Order(
  val id : String,
  val price : Double
) 
val orderList = ......
val sum = orderList.sumOf { it.price }
data class Product(val name: String, val quantity: Int) {
}
fun main(args: Array<String>) {
    val productList = listOf(
            Product("A", 100),
            Product("B", 200),
            Product("C", 300)
    )
    val totalPriceInList1: Int = productList.map { it.quantity }.sum()
    println("sum(): " + totalPriceInList1)
    val totalPriceInList2: Int = productList.sumBy { it.quantity }
    println("sumBy(): " + totalPriceInList2)
} 

这是我们代码的结果

sum(): 600
sumBy(): 600 

相关内容

  • 没有找到相关文章

最新更新