如何在Scala中将指定列表转换为目标嵌套Map结构?
Scala 实现列表到嵌套Map的转换
需求说明
输入是包含用户ID与SubscriptionState样例类的元组列表,需要转换为嵌套Map:
- 外层Map的键为用户ID
- 内层Map的键是合并了相同
channel+state的SubscriptionState(合并所有关联的subIds),值为该状态的出现次数
前置定义
首先补充必要的枚举类型(假设Channel和ChannelState是枚举):
object Channel extends Enumeration { val CNN, SKY, FOX = Value } object ChannelState extends Enumeration { val ONLINE, OFFLINE = Value } import Channel._ import ChannelState._ case class SubscriptionState(channel: Channel.Value, state: ChannelState.Value, subIds: Seq[Long])
输入数据
val input = 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))) )
转换实现
val result: Map[Int, Map[SubscriptionState, Int]] = input // 1. 按用户ID分组,得到每个用户对应的所有条目 .groupBy(_._1) // 2. 处理每个用户的条目集合 .mapValues { userEntries => userEntries // 提取当前用户的所有SubscriptionState .map(_._2) // 3. 按channel和state组合键分组,合并相同状态的条目 .groupBy(ss => (ss.channel, ss.state)) // 4. 对每个分组生成合并后的SubscriptionState和计数 .map { case ((channel, state), ssList) => // 合并subIds:去重并排序,与示例输出格式一致 val mergedSubIds = ssList.flatMap(_.subIds).distinct.sorted // 统计该状态的出现次数 val count = ssList.size SubscriptionState(channel, state, mergedSubIds) -> count } }
逻辑解释
- 用户分组:通过
groupBy(_._1)将输入列表按用户ID拆分,得到每个用户对应的所有状态条目。 - 状态分组:对每个用户的状态条目,按
(channel, state)组合键分组——只有channel和state完全一致的状态才需要合并subIds。 - 合并与计数:对每个分组,将所有
subIds扁平合并后去重排序,创建新的SubscriptionState对象,同时记录该分组的元素数量(即状态出现次数)。
内容的提问来源于stack exchange,提问作者Zy0n
相关产品推荐
相关产品推荐

