Daniel Gretzke
Daniel Gretzke

Reputation: 446

Is there a sumBy equivalent for multiplication?

I have an array of classes with values. E.g.

class MyData(val value: Double)

class MyClass(val values: List<MyData>)

it's pretty easy to get the sum of all values in the array:

values.sumByDouble { it.value }

Is there an equivalent to multiply these values inside those classes?

Upvotes: 0

Views: 391

Answers (2)

Willi Mentzel
Willi Mentzel

Reputation: 29844

There is no dedicated function for that, but you can use reduce for that. But there is a problem. Since the element (in this case of type T with S as upper bound) has to be a subtype of the accumulator (in this case of type S),

inline fun <S, T : S> Iterable<T>.reduce(
    operation: (acc: S, T) -> S
): S

which is not the case in your example, it would be a good idea to first map the MyData elements to the Double value:

val l = listOf(MyData(1.0), MyData(2.0), MyData(3.0))
    .map { it.value }
    .reduce { acc, ele -> acc * ele }

println(l) // 6.0

Alternatively, you could change your data model (like shown here) but that might not be a good idea just for the sake of multiplying all values, but it depends on your use-case.

Upvotes: 1

JavierSA
JavierSA

Reputation: 801

You can create an extension function:

public inline fun <T> Iterable<T>.multiplyByDouble(selector: (T) -> Double): Double {
    this.firstOrNull() ?: return 0.0
    var result = 1.0
    for (element in this) {
        result *= selector(element)
    }
    return result
}

and use it:

listOf(2.0, 3.0).multiplyByDouble { it }  // 6.0
listOf<Double>().multiplyByDouble { it }  // 0.0

Upvotes: 2

Related Questions