Kotlin: BigDecimal amount listed

I have a list that I want to filter, and then return an id card with the sum of the amounts:

val totalById = list .filter { it.status == StatusEnum.Active } .groupBy { it.item.id } .mapValues { it.value.sumBy { it.amount } } 

"it.amount" is BigDecimal, but it looks like sumBy only Int.

For java 8 it will be:

Collectors.groupingBy(i-> i.getItem().getId(), Collectors.mapping(Item::getAmount, Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))))

Is there any way to do this in Kotlin?

+5
source share
3 answers

Just as you used Collectors.reducing in java, you can use the fold or reduce extension functions in Kotlin:

 val bigDecimals: List<BigDecimal> = ... val sum = bigDecimals.fold(BigDecimal.ZERO) { acc, e -> acc + e } // or val sum2 = bigDecimals.fold(BigDecimal.ZERO, BigDecimal::add) 
+7
source

You can create your own sumByBigDecimal extension sumByBigDecimal , similar to sumByDouble . eg:.

 /** * Returns the sum of all values produced by [selector] function applied to each element in * the collection. */ inline fun <T> Iterable<T>.sumByBigDecimal(selector: (T) -> BigDecimal): BigDecimal { var sum: BigDecimal = BigDecimal.ZERO for (element in this) { sum += selector(element) } return sum } 

Usage example:

 val totalById = list .filter { it.status == StatusEnum.Active } .groupBy { it.item.id } .mapValues { it.value.sumByBigDecimal { it.amount } } 
+4
source

Combining the bend approach and the extension function approach, you can do this:

 fun Iterable<BigDecimal>.sumByBigDecimal(): BigDecimal { return this.fold(BigDecimal.ZERO) { acc, e -> acc + e } } fun <T> Iterable<T>.sumByBigDecimal(transform: (T) -> BigDecimal): BigDecimal { return this.fold(BigDecimal.ZERO) { acc, e -> acc + transform.invoke(e) } } 

Use them as follows:

 listOfBigs.sumByBigDecimal() listOfWidgets.sumByBigDecimal { it.price } 
0
source

Source: https://habr.com/ru/post/1257533/


All Articles