osumatu
osumatu

Reputation: 442

Scala sum on multiple columns in groupby

I am trying to implement SQL Group By & SUM logic into a Scala function.

I have a list of objects,

case class TypeToSum(id: Int, active_total: Int, inactive_total: Int)

I am filling the list by merging multiple lists. Finally, list looks like:

{id: 1, active_total: 4, inactive_total: 3},
{id: 1, active_total: 2, inactive_total: 5},
{id: 1, active_total: 1, inactive_total: 1},
{id: 2, active_total: 2, inactive_total: 7},
{id: 2, active_total: 6, inactive_total: 2}

My aim is to reach following result:

{id: 1, active_total: 7, inactive_total: 9},
{id: 2, active_total: 8, inactive_total: 9}

Basically I need to get sum of those columns while grouping by id. In another function I needed to get sum on one column and I could do it with following code:

   lossTotals.groupBy(totals => (totals.product_id, totals.part_id))
      .mapValues(_.map(_.loss_sum).sum).map( .... )

How can I implement this approach (or another one) to get multiple sum operations on different fields within the same list?

Upvotes: 0

Views: 547

Answers (1)

João Guitana
João Guitana

Reputation: 241

You could do something like this:

case class TypeToSum(id: Int, active_total: Int, inactive_total: Int) {
  def merge(other: TypeToSum) = TypeToSum(id, active_total + other.active_total, inactive_total + other.inactive_total)
}

val ls = List(
  TypeToSum(id = 1, active_total = 4, inactive_total = 3),
  TypeToSum(id = 1, active_total = 2, inactive_total = 5),
  TypeToSum(id = 1, active_total = 1, inactive_total = 1),
  TypeToSum(id = 2, active_total = 2, inactive_total = 7),
  TypeToSum(id = 2, active_total = 6, inactive_total = 2))

val sum = ls
  .groupBy(_.id)
  .mapValues {
    case Nil => None
    case List(x) => Some(x)
    case ls => Some(ls.tail.foldLeft(ls.head)(_ merge _))
  }
  .values.flatten

println(sum)

Upvotes: 1

Related Questions