Reputation: 5
I am trying to pass a function and want to use reduce on it. This is the data class
data class TestClass(
var variable1: BigDecimal?,
var variable2: BigDecimal?
)
This is the function which I want to work
fun aggregateAll() {
helperfunc(TestClass::variable1::get,someDummmyFilledListOfTestClass)
}
fun helperfunc(function: () ->BigDecimal, testList:List<TestClass>) {
var aggregatedValue:BigDecimal = BigDecimal.ZERO
testList.map{function}.reduce{aggregatedValue,element -> aggregatedValue.add(element)}
}
Upvotes: 0
Views: 169
Reputation: 9672
fun main() {
val someDummmyFilledListOfTestClass = listOf<TestClass>(
TestClass(1.toBigDecimal()),
TestClass(199.toBigDecimal()),
TestClass(null),
TestClass(501.toBigDecimal())
)
val result = helperfunc(someDummmyFilledListOfTestClass, TestClass::variable1::get)
// trailing lambda
// or val result = helperfunc(someDummmyFilledListOfTestClass) { it.variable1 }
println(result)
}
/* lambda last parameter for trailing lambda */
fun helperfunc(testList: List<TestClass>, function: (TestClass) -> BigDecimal?): BigDecimal {
return testList
// map TestClass to BigDecimal? and filter nulls
.mapNotNull(function)
// fold with initial value, reduce will throw exception if list is empty
.fold(BigDecimal.ZERO) { acc, element -> acc.add(element) }
}
data class TestClass(
var variable1: BigDecimal?
// var variable2: BigDecimal?
)
Upvotes: 2
Reputation: 93581
For the map
function to work, your function type needs a TestClass
parameter, so it should be (TestClass) -> BigDecimal
.
And your variable1
needs to be non-nullable, or it else its getter is a (TestClass) -> BigDecimal?
, which doesn't match the required type.
And when you pass the function to map
, don't wrap it in a lambda, because then you are just creating a function that returns your other function.
And you seem to want to use a separate aggregator rather than the first element of the list, so that means you should use fold
instead of reduce
.
data class TestClass(
var variable1: BigDecimal,
var variable2: BigDecimal?
)
fun aggregateAll() {
helperfunc(TestClass::variable1::get, someDummmyFilledListOfTestClass)
}
fun helperfunc(function: (TestClass) -> BigDecimal, testList:List<TestClass>) {
val sum: List<BigDecimal> =
testList.map(function).fold(BigDecimal.ZERO) { aggregatedValue, element -> aggregatedValue.add(element)}
}
Upvotes: 2