水善利万物而不争,处众人之所恶,故几于道
对List中的单词进行统计,并取计数排名前三的结果。要求使用Scala中的函数。期望输出结果:List((Hello,4), (Scala,3), (Hbase,2))
待处理集合:
val stringList = List("Hello Scala Hbase kafka", "Hello Scala Hbase", "Hello Scala", "Hello")
思路分析:
1. 要对这个集合进行词频统计,首先应该拿到每个单词
2. 拿到每个单词后,要得到(hello,4)这样的格式就要进行分组,分组依据是单词自己
3. 拿到想要的格式后,就要进行排序,然后取前3
第一步:
要拿到每个单词,首先进行切割,然后扁平化,可以先用map映射,然后再flatten,分两步进行。但是有个flatMap
它可以先进行映射然后扁平化,一步完成,所以我这里选择这种方式。
val split: List[String] = stringList.flatMap(_.split(" "))
println(split)
输出结果:
List(Hello, Scala, Hbase, kafka, Hello, Scala, Hbase, Hello, Scala, Hello)
第二步:
对单词进行分组。用groupBy
函数
val group: Map[String, List[String]] = split.groupBy(word => word)
println(group)
输出结果:
Map(Hello -> List(Hello, Hello, Hello, Hello), Hbase -> List(Hbase, Hbase), kafka -> List(kafka), Scala -> List(Scala, Scala, Scala))
分组后格式不是我们想要的,应该将value位置映射为它的集合大小,所以再进行一次map
映射。使用size
取到集合大小
val count: Map[String, Int] = group.map(
mapkv => {
(mapkv._1, mapkv._2.size)
}
)
println(count)
输出结果:
Map(Hello -> 4, Hbase -> 2, kafka -> 1, Scala -> 3)
第三步:
排序,取前三。我们直接对这样的map集合进行排序的时候发现根本没有sort相关的函数方法,查看排序相关的方法,发现三个排序方法都在SeqLike特质下,所以只有seq下的集合才能排序,因此将map转换为seq下的集合,使用toList
将map转换为List
val listWord: List[(String, Int)] = count.toList
println(listWord)
输出结果:
List((Hello,4), (Hbase,2), (kafka,1), (Scala,3))
转换好以后,选择排序函数。其中sortBy、sortWith
都可以。排好序后,用take
取前三就可以了
//val res: List[(String, Int)] = listWord.sortBy(_._2).reverse.take(3) 排好序后反转
//val res: List[(String, Int)] = listWord.sortBy(-_._2).take(3) 直接取反排序
val res: List[(String, Int)] = listWord.sortWith(_._2 > _._2).take(3) //两个元素怒比较排序
println(res)
输出结果:
List((Hello,4), (Scala,3), (Hbase,2))
// 单词计数:将集合中出现的相同的单词,进行计数,取计数排名前三的结果
val stringList = List("Hello Scala Hbase kafka", "Hello Scala Hbase", "Hello Scala", "Hello")
val split: List[String] = stringList.flatMap(_.split(" "))
println(split)
val group: Map[String, List[String]] = split.groupBy(word => word)
println(group)
val count: Map[String, Int] = group.map(
mapkv => {
(mapkv._1, mapkv._2.size)
}
)
println(count)
val listWord: List[(String, Int)] = count.toList
println(listWord)
//val res: List[(String, Int)] = listWord.sortBy(_._2).reverse.take(3) 排好序后反转
//val res: List[(String, Int)] = listWord.sortBy(-_._2).take(3) 直接取反排序
val res: List[(String, Int)] = listWord.sortWith(_._2 > _._2).take(3) //两个元素怒比较排序
println(res)