如何将CompactBuffer转换为List并实现分组内容排序?
Scala分组后转List及分组内排序的简便方案
先快速梳理下你的场景:
你的data.csv内容是:
1,Lokesh 2,Bhupesh 2,Amit 2,Ratan 2,Dinesh 1,Pavan 1,Tejas 2,Sheela 1,Kumar 1,Venkat
通过这段Scala代码读取分组:
val r = sc.textFile("data96/data.csv") val rm = r.map(x=>(x.split(",")(0), x.split(",")(1))) val r_grp = rm.groupByKey
得到的结果是Array[(String, Iterable[String])],其中分组值是CompactBuffer格式:
Array((2,CompactBuffer(Bhupesh, Amit, Ratan, Dinesh, Sheela)), (1,CompactBuffer(Lokesh, Pavan, Tejas, Kumar, Venkat)))
接下来针对你的两个需求给出简便方案:
一、把CompactBuffer转为List的简单方法
完全不用复杂的combineByKey!因为CompactBuffer本身就是Iterable的子类,直接用mapValues配合.toList就能轻松转换:
// 直接将每个分组的Iterable转为List val r_grp_list = rm.groupByKey().mapValues(_.toList)
执行后得到的就是Array[(String, List[String])]类型的结果,完美替代combineByKey的复杂实现。
二、对分组内内容进行升序/降序排序
排序操作可以直接和转List的步骤结合起来,非常灵活:
1. 升序排序
用Scala内置的.sorted方法(默认按字符串字典序升序):
// 分组后转List并升序排序 val r_grp_asc = rm.groupByKey().mapValues(_.toList.sorted)
结果里的每个分组都会变成有序的List:
Array((2,List(Amit, Bhupesh, Dinesh, Ratan, Sheela)), (1,List(Kumar, Lokesh, Pavan, Tejas, Venkat)))
2. 降序排序
有两种常用的简便方式:
- 方式一:直接使用反向排序器
val r_grp_desc1 = rm.groupByKey().mapValues(_.toList.sorted(Ordering[String].reverse))
- 方式二:先升序排序再反转List
val r_grp_desc2 = rm.groupByKey().mapValues(_.toList.sorted.reverse)
两种方式都能得到降序的分组结果:
Array((2,List(Sheela, Ratan, Dinesh, Bhupesh, Amit)), (1,List(Venkat, Tejas, Pavan, Lokesh, Kumar)))
如果你的需求是先排序再转List,也可以写成_.sorted.toList,效果完全一致,看个人习惯选择就行。
内容的提问来源于stack exchange,提问作者Choix
相关产品推荐
相关产品推荐

