自己编写的拙劣的代码
object WordCount extends App {
val file = Source.fromFile("D:/data.txt")
var words: String = ""
var wordArray = new ArrayBuffer[String]()
//把行连成字符串
for (f <- file.getLines()) {
words += f + "\t"
}
var wordMap = mutable.HashMap[String, Int]()
//变成数组
wordArray = splitWord(words)
//变成map,value值为0
wordArray.map(x => wordMap += (x -> 0))
//统计数组中各元素出现的次数,map中已经有所有元素各一份了(value为0)
for (i<-wordArray){
if (wordMap.getOrElse(i,-1)!=(-1)){
wordMap(i) = wordMap(i)+1
}
}
println(wordMap)
//分割字符串
def splitWord(word: String) = {
wordArray ++= word.split("\t")
}
}
网上大神的优秀代码
需要使用Spark
scala> var f1=sc.textFile("/tmp/dataTest/followers.txt")
scala> f1.flatMap(x=>x.split("-")).map((_,1)).collect //每个数字以'-'分割,并数字为key,给每个key赋值1
res10: Array[(String, Int)] = Array((2,1), (1,1), (4,1), (1,1), (1,1), (2,1), (6,1), (3,1), (7,1), (3,1), (7,1), (6,1), (6,1), (7,1), (3,1), (7,1))
reduceByKey(_+_).collect 将key相同元素合并(4出现一次,7出现4次,6出现3次,2出现2次,3出现3次,1出现3次)
scala> f1.flatMap(x=>x.split("-")).map((_,1)).reduceByKey(_+_).collect
res12: Array[(String, Int)] = Array((4,1), (7,4), (6,3), (2,2), (3,3), (1,3))
对出现的次数进行排序
sortByKey
scala> var resText=f1.flatMap(x=>x.split("-")).map((_,1)).reduceByKey(_+_).map(x=>(x._2,x._1)).sortByKey(false).map(x=>(x._2,x._1))
resText: org.apache.spark.rdd.RDD[(String, Int)] = MapPartitionsRDD[39] at map at <console>:26
对出现的次数进行排序,所以要先将元素的第二个元组和第一个元组互换位置map(x=>(x._2,x._1)),这样出现的次数就成了key,然后再对key进行排序sortByKey(false)
再对排序后的结果,再一次的对他们的元组进行互换位置(次数,单词)换后(单词,次数)map(x=>(x._2,x._1))
false:从大到小 降序
true:小小到大 升序
简便方法:
reduceByKey(_ + _).sortBy(_._2,false)
也可以实现排序
只用Scala完成
val lines = List("hello tom hello jerry", "hello tom hello kitty hello china")
val wc = lines.flatMap(_.split(" ")).map((_, 1)).groupBy(_._1).map(t => (t._1, t._2.size)).toList.sortBy(_._2).reverse
val wc2 = lines.flatMap(_.split(" ")).map((_, 1)).groupBy(_._1).mapValues(_.size)
val wc3 = lines.flatMap(_.split(" ")).map((_, 1)).groupBy(_._1).mapValues(_.foldLeft(0)(_ + _._2))
以上用到的方法
reduceByKey
reduce方法的作用是把所有元素按照指定的方法进行处理,如f1.reduce((x, y)=>x+y),就是把f1中的元素依次按照x+y来加起来,最后的结果是所有元素的和。
reduceByKey的用处就是根据key来进行reduce处理,就是说在key相同的情况下进行处理
flatMap
flatMap=map+flatten
map把每个元素都做一个相同的操作,flatten是把嵌套的变成在同一个里面,如val f = List(List(1,2),List(3,4),List(5,6)) 执行 f.flatten的结果就是List(1,2,3,4,5,6)
所以f.flatMap(.map(*2))的结果是List(2,4,6,8,10,12)相当于f.map(.map(*2)).flatten,是先执行map,再执行flatten
groupBy
groupBy按照元素分组返回map
groupBy(_._1)第一个_表示List中的每一个元组,取元组中的某一个元素用._n,即按照元组中的某一元素分组,返回是一个map
mapValues
mapValues指的是key 不动,只是对values进行处理,结果 k v 一起返回。
mapValues(_.size)中的_指的就是v