Scala中集合的方法求wordCount代码解析

wordcount的详细分析
def main ( args: Array [ String ]) : Unit = {
// 文本拆分成多行,把多行转换成一个集合
val list: List [ String ] = Source. fromFile ( "input/word.txt" ) .getLines () .toList
println ( list )
//flatmap 是先 map flatten
// 此时文本中的每一行就是一个元素,下面的下划线就是一行
// 得到的结果是一个一个的单词
val wordList: List [ String ] = list.flatMap ( _.split ( " " ))
// 对每个单词进行转换操作(单词, 1
val word2OneList: List [( String , Int )] = wordList.map (( _, 1 ))
// 上面得到的结果是一个集合,集合中的内容是:( hello,1 (word,1)(word,1)(hello,1)...
// 根据每个元素的 key 进行分组
// 表示的是按照对偶元素中的第一个元素 ( 单词 ) 分组。第一个下划线是每个元组,第二个 _1, 表示的是元组中的第一个元素
val word2ListMap: Map [ String , List [( String , Int )]] = word2OneList.groupBy ( _._1 )
println ( word2ListMap )
// 上面是一个 map 集合,注意一下 map 的类型,表示的是相同的元组是放到了同一个 list 集合
// 上面的 Map 中的每个元素的格式是(单词名 ->List(( 单词名, 1) (单词名, 1 )(单词名, 1 )
//Map中 元素的本质是元组,元组的第一个元素代表单词,第二个元素是一个 list 集合。最终操作的是每个元组
//map 当中 -> 其实就是逗号的意思
val word2CountMap: Map [ String , Int ] = word2ListMap.map ( //map 后的小括号需要我们传递一个逻辑,使用匿名函数:() =>{}
kv => { //kv 表示的就是拿到的每个元素,元素的格式是: (单词名 ->List(( 单词名, 1) (单词名, 1 )(单词名, 1 )
// 最后统计的格式是 ( hello,4 (word,3) 这种形式
( kv._1, kv._2.size ) // 格式就是(单词,对应的单词所在的集合的长度)
}
)
println ( word2CountMap )
/*
解析一下步骤 :文本 --> 多行 --> (把每一行用空格拆分,把每行扁平化成一个一个单词) -->( 单词名, 1)--> 按照单词的名称进行分组 --> 最后进行 map (单词名,单词所在的集合的长度)
1 getlines.tolist: 把文本当中的每一行拿到。形成一个集合(集合当中的每个元素,就是文本当中的一行)
2 flatmap:flatmap 是先进行 map 操作,再进行 flatten 。先对每个元素(每一行)进行空格拆分,再对每一行进行扁平化操作(把一行,拆分出多个个体)
3 、扁平化之后,就是一个一个的单词了,这些单词在一个集合当中,只不过是单词之间无序,比较散。后面需要做的就是把相同的单词放到一起
4 、现在是为了把一个 List 集合中的元素变成 (单词, 1
5 、然后对集合中的元素进行分组,每个元素相同的 key 分到一组
6 、对 Map 中的每个元素进行 map 操作
注意:每次操作需要查看一下返回值类型,最好是每次都打印一下新的集合,可以帮助自己对集合中元素格式的理解
*/
}
 
遇到的问题.
1、自己想省略小括号,发现省略不了
Scala中集合的方法求wordCount代码解析
2、每个操作都会返回一个新的集合

 
Scala中集合的方法求wordCount代码解析
 
map是无序的,如果要排序需要转换成list
Scala中集合的方法求wordCount代码解析
 
取前3: Scala中集合的方法求wordCount代码解析
 

有点难度的wordCount
 
问题:
求这种形式的wordcount:
val dataList = List (
( "Hello Scala" , 4 ) , ( "Hello Spark" , 2 )
)
 
代码:
Scala中集合的方法求wordCount代码解析
 
到这一步的时候被卡住,相同单词已经被分到同一个组当中,但是不知道如何去聚合相同单词的数量
很好的思路:因为后面的转换其实不需要了元组中的第一个元素了。只需要转换成 hello->List(4,2)
所以在map的时候,就只拿元组中的第二个元素,也就是 Scala中集合的方法求wordCount代码解析,第一个_2 是List 集合,第二个_2是元组中的第二个元素。
这个问题解决了后面也就流畅了
Scala中集合的方法求wordCount代码解析
 
 
另外一种:类似九层妖塔,字符串和数字是可以相乘的
Scala中集合的方法求wordCount代码解析

wordcount 难度版
object ScalaWordCount6 {
def main ( args: Array [ String ]) : Unit = {
//("zhangsan", " 河北 ", " "),
val tupleList = List (
( "zhangsan" , " 河北 " , " " ) ,
( "lisi" , " 河北 " , " 衣服 " ) ,
( "wangwu" , " 河北 " , " " ) ,
( "zhangsan" , " 河南 " , " " ) ,
( "lisi" , " 河南 " , " 衣服 " ) ,
( "wangwu" , " 河南 " , " " ) ,
( "zhangsan" , " 河南 " , " " ) ,
( "lisi" , " 河北 " , " 衣服 " ) ,
( "wangwu" , " 河北 " , " " ) ,
( "zhangsan" , " 河北 " , " " ) ,
( "lisi" , " 河北 " , " 衣服 " ) ,
( "wangwu" , " 河北 " , " 帽子 " ) ,
( "zhangsan" , " 河南 " , " " ) ,
( "lisi" , " 河南 " , " 衣服 " ) ,
( "wangwu" , " 河南 " , " 帽子 " ) ,
( "zhangsan" , " 河南 " , " " ) ,
( "lisi" , " 河北 " , " 衣服 " ) ,
( "wangwu" , " 河北 " , " 帽子 " ) ,
( "lisi" , " 河北 " , " 衣服 " ) ,
( "wangwu" , " 河北 " , " 电脑 " ) ,
( "zhangsan" , " 河南 " , " " ) ,
( "lisi" , " 河南 " , " 衣服 " ) ,
( "wangwu" , " 河南 " , " 电脑 " ) ,
( "zhangsan" , " 河南 " , " 电脑 " ) ,
( "lisi" , " 河北 " , " 衣服 " ) ,
( "wangwu" , " 河北 " , " 帽子 " )
)
val tuplesNewList: List [( String , String )] = tupleList.map (( tuple ) => {
( tuple._2, tuple._3 )
})
println ( tuplesNewList )
/*
分析的一步步逻辑
(" 河北 " " 鞋子 ") (" 河北 " " 袜子 "),(" 河北 " " 鞋子 "),(" 河北 " " 衣服 ")
" 河北 " ->List( " 鞋子 " 4 ),( " 衣服 " 6 )
" 河南 "->List( " 鞋子 " 4 ),( " 衣服 " 6 )
*/
println ( tuplesNewList.groupBy ( _._1 ))
val proviceToGoods: Map [ String , List [( String , String )]] = tuplesNewList.groupBy ( _._1 )
val goods: Map [ String , List [ String ]] = proviceToGoods.map (( kv ) => {
( kv._1, kv._2.map ( _._2 ))
})
println ( goods )
val goodsRudeuce: Map [ String , Map [ String , List [ String ]]] = goods.map (( kv ) => {
( kv._1, kv._2.groupBy (( good ) => {
good
}))
})
println ( goodsRudeuce )
val proviceToGoodsCount: Map [ String , Map [ String , Int ]] = goodsRudeuce.map (( kv ) => {
( kv._1, kv._2.map (( good ) => {
( good._1, good._2.size )
}))
})
println ( proviceToGoodsCount )
val list: List [( String , Map [ String , Int ])] = proviceToGoodsCount.toList
println ( list )
val tuples: List [( String , List [( String , Int )])] = list.map { info => {
val pro: String = info._1
val goods: List [( String , Int )] = info._2.toList
val res: List [( String , Int )] = goods.sortBy ( _._2 )( Ordering .Int.reverse )
( pro, res )
}
}
println ( tuples )
}
}
 
结果:
Scala中集合的方法求wordCount代码解析