Is there a way in Kotlin for doing the sum()
operation on a filtered list of numbers, without actually filtering out the elements first?
I'm looking for something like this:
val nums = listOf<Long>(-2, -1, 1, 2, 3, 4)
val sum = nums.sum(it > 0)
Statement: Given a set of positive integers, and a value sum, determine that the sum of the subset of a given set is equal to the given sum. Given an array of integers and a sum, the task is to have all subsets of given array with sum equal to the given sum. Subset {4, 5} has the sum equal to 9.
If a set has “n” elements, then the number of subset of the given set is 2n and the number of proper subsets of the given subset is given by 2n-1. Consider an example, If set A has the elements, A = {a, b}, then the proper subset of the given subset are { }, {a}, and {b}.
sumBy and sumByDouble are Deprecated
from kotlin 1.5
. You can check those link.
Use sumOf to get sum on a List
or Array
sumOf
Returns the sum of all values produced by selector function applied to each element in the collection or Array.
Example:
data class Order(
val id : String,
val price : Double
)
val orderList = ......
val sum = orderList.sumOf { it.price }
You can make use of 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
}
You can pass a function to it where the function transforms negative value to 0. So, it sums up all values in the list which is greater than 0 since adding 0 makes no effect to the result.
val nums = listOf<Long>(-2, -1, 1, 2, 3, 4)
val sum = nums.sumBy { if (it > 0) it.toInt() else 0 }
println(sum) //10
If you require a Long
value back, you have to write an extension for Long
just like 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
}
Then, the toInt()
conversion can be taken away.
nums.sumByLong { if (it > 0) it else 0 }
As suggested by @Ruckus T-Boom, if (it > 0) it else 0
can be simplified using Long.coerceAtLeast()
which returns the value itself or the given minimum value:
nums.sumByLong { it.coerceAtLeast(0) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With