object WCDemo {
def main(args: Array[String]): Unit = {
val lineList = List("hello tom hello jerry", "hello jerry", "hello kitty")
val wordList = lineList.map(_.split(" ")) //wordList: List[Array[String]] = List(Array(hello, tom, hello, jerry), Array(hello, jerry), Array(hello, kitty))
val wordList1 = wordList.flatten // wordList1: List[String] = List(hello, tom, hello, jerry, hello, jerry, hello, kitty)
val wordMap = wordList1.map(_ -> 1) // wordMap: List[(String, Int)] = List((hello,1), (tom,1), (hello,1), (jerry,1), (hello,1), (jerry,1), (hello,1), (kitty,1))
val wordMap1 = wordMap.groupBy(_._1) // wordCount: scala.collection.immutable.Map[String,List[(String, Int)]] = Map(tom -> List((tom,1)), kitty -> List((kitty,1)), jerry -> List((jerry,1), (jerry,1)), hello -> List((hello,1), (hello,1), (hello,1), (hello,1)))
val result = wordMap1.map(t => (t._1,t._2.size)) // result: scala.collection.immutable.Map[String,Int] = Map(tom -> 1, kitty -> 1, jerry -> 2, hello -> 4)
println("result : " + result) //Map(tom -> 1, kitty -> 1, jerry -> 2, hello -> 4)
// 写成一行如下
val result2 = lineList.flatMap(_.split(" ")).map(_ -> 1).groupBy(_._1).map(t => (t._1, t._2.size))
println("wc result2 : " + result2)
}
}
代码说明:
1、lineList.map(_.split(” “))
map:通过一个函数重新计算列表中所有元素,并且返回一个相同数目元素的新列表。
如上将每个元素取出再通过空格进行分割,从而返回相同数目过犹不及的新列表2、wordList.flatten
- flatten:把嵌套的结构展开,或者说flatten可以把一个二维的列表展开成一个一维的列表。
- 如上将List中的Array打开形成一维的新列表,如果是Set则会根据Set的性质将重复的删除掉
val ys = Set(
List(1, 2, 3),
List(3, 2, 1)
).flatten
// ys == Set(1, 2, 3)val xs = List(
Set(1, 2, 3),
Set(1, 2, 3)
).flatten
// xs == List(1, 2, 3, 1, 2, 3)
3、wordList1.map(_ -> 1)
- 这一步与第一步同理,需要注意的是 -> 这个符号是将每个元素转换成元组(xx,1)的格式以便后面进行分组
- 其实这一步可以与第二结合起来用flatMap方法便可。
- flatMap:flatMap结合了map和flatten的功能,接收一个可以处理嵌套列表的函数,然后把返回结果连接起来。
4、wordMap.groupBy(_._1)
- groupBy:是对集合中的元素进行分组操作,结果得到的是一个Map。
- 如上按元组中第一个值即单词来分组,得到Map
5、wordCount.map(t => (t._1,t._2.size))
- 这一步可根据第4步中的Map可知,只要确定Map中每个key对应的values中List的大小便可计算出词频了。
- 因为map(._1,.2.size)中的参数并不支持直接传两个“”参数调用,所以可直接传入一个匿名函数来获取所需要的两个值