Home > Enterprise >  How to transform input data into following format? - groupby
How to transform input data into following format? - groupby

Time:11-17

What I have is the following input data for a function in a piece of scala code I'm writing:

List(
  (1,SubScriptionState(CNN,ONLINE,Seq(12))), 
  (1,SubScriptionState(SKY,ONLINE,Seq(12))), 
  (1,SubScriptionState(FOX,ONLINE,Seq(12))), 
  (2,SubScriptionState(CNN,ONLINE,Seq(12))), 
  (2,SubScriptionState(SKY,ONLINE,Seq(12))), 
  (2,SubScriptionState(FOX,ONLINE,Seq(12))), 
  (2,SubScriptionState(CNN,OFFLINE,Seq(13))), 
  (2,SubScriptionState(SKY,ONLINE,Seq(13))), 
  (2,SubScriptionState(FOX,ONLINE,Seq(13))), 
  (3,SubScriptionState(CNN,OFFLINE,Seq(13))), 
  (3,SubScriptionState(SKY,ONLINE,Seq(13))), 
  (3,SubScriptionState(FOX,ONLINE,Seq(13)))
)

SubscriptionState is just a case class here:

case class SubscriptionState(channel: Channel, state: ChannelState, subIds: Seq[Long])

I want to transform it into this:


Map(
  1 -> Map(
        SubScriptionState(SKY,ONLINE,Seq(12)) -> 1, 
        SubScriptionState(CNN,ONLINE,Seq(12)) -> 1, 
        SubScriptionState(FOX,ONLINE,Seq(12)) -> 1),

  2 -> Map(
        SubScriptionState(SKY,ONLINE,Seq(12,13)) -> 2, 
        SubScriptionState(CNN,ONLINE,Seq(12)) -> 1, 
        SubScriptionState(FOX,ONLINE,Seq(12,13)) -> 2, 
        SubScriptionState(CNN,OFFLINE,Seq(13)) -> 1),  

  3 -> Map(
        SubScriptionState(SKY,ONLINE,Seq(13)) -> 1, 
        SubScriptionState(FOX,ONLINE,Seq(13)) -> 1, 
        SubScriptionState(CNN,OFFLINE,Seq(13)) -> 1)
)

How would I go about doing this in scala?

CodePudding user response:

Here is my approach to the problem. I think it may not be a perfect solution, but it works as you would expect.

  val result: Map[Int, Map[SubscriptionState, Int]] = list
    .groupBy(_._1)
    .view
    .mapValues { statesById =>
      statesById
        .groupBy { case (_, subscriptionState) => (subscriptionState.channel, subscriptionState.state) }
        .map { case (_, groupedStatesById) =>
          val subscriptionState = groupedStatesById.head._2 // groupedStatesById should contain at least one element
          val allSubIds = groupedStatesById.flatMap(_._2.subIds)
          val updatedSubscriptionState = subscriptionState.copy(subIds = allSubIds)
          updatedSubscriptionState -> allSubIds.size
        }
    }.toMap
  • Related