Scala函数综合练习 - WordCount

水善利万物而不争,处众人之所恶,故几于道

目录

一、思路分析及步骤详解
二、完整程序

一、思路分析及步骤详解

对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)

你可能感兴趣的:(Scala,scala,开发语言,函数练习,WordCount)