scala练习(一)

一、scala wordcount
(***数据处理要在map中)

1.先将数据导入到scala
import scala.io.Source
val lines = Source.fromFile("./The_man_of_property.txt").getLines().toList
lines.map(x=>x.split(" ")).flatten
等价于
lines.flatMap(x=>x.split(" "))
lines.flatMap(_.split(" "))
.map((_,1))
.groupBy(_._1)
从tuple(forgotten,1)中把第一个单词提出来forgotten作为key,
把整个tuple作为value,收集到一个list中
这样对应的value是一个list里面包含所有对应key的tuple
例:这样的形式,_._1取出的是forgotten, _._2取出的是:List((forgotten,1), (forgotten,1), (forgotten,1))
_1:forgotten -> _2:List((forgotten,1), (forgotten,1), (forgotten,1))

整个list大小就是对应key:forgotten出现的次数
lines.flatMap(_.split(" ")).map((_,1)).groupBy(_._1).map(x=>(x._1,x._2.size))  就是把_._2的list的大小
如果不通过list大小来算具体单词的次数(词频)
就像要讲map中的list中的第二个值相加
lines.flatMap(_.split(" ")).map((_,1))
	.groupBy(_._1)
	.map(x=>(x._1,x._2.map(_._2).sum))

topN:取前N个值
需要进行数组的切片:
指定返回数组中的多少个数
top10: slice(0,10)

lines.flatMap(_.split(" ")).map((_,1)).groupBy(_._1).map(x=>(x._1,x._2.size)).toList.sortBy(_._2).reverse.slice(0,5)(3)._1
取数组用(3),取tuple里面的值用_._1的方式

另一种wordcount写法

lines.flatMap(_.split(" ")).map((_,1)).groupBy(_._1).mapValues(_.map(_._2).sum)
返回的是一个Map(dict),key:单词,value:词频
lines.flatMap(_.split(" ")).map((_,1)).groupBy(_._1).mapValues(_.size).toArray.sortWith(_._2>_._2).slice(0,10)

重点知识:

a.foldLeft(0)(_+_)
①.
sum = 0
for i in a:
	sum += i
return sum
上面第一个_  就是i,0就是sum,第二个_ 就是下面sum+=i的i。

②.tuple求和
sum = 0
for i in a:
	sum += i[1]
return sum
a.foldLeft(0)(_+_._2)
上面第一个_  就是i,0就是sum,第二个_._2 就是下面sum+=i的i[1]。因为python里下标是从0开始,scala从1开始。

正则处理

python 里:
import re
p = r'[0-9]+'
p.findall(s)这个是一个数组
p.findall(s)[0]

scala里:
val p = "[0-9]+".r
val s = "546465sfgidg"
p.findAllIn(s).toArray
p.findAllIn(s).foreach(x=>println(x))
p.findAllIn(s).mkString("")
mkString("[","","]")


取标点,只取数字和字符(对上面的数据)
val p = "[0-9a-zA-Z]+".r
lines.flatMap(_.split(" ")).map(x=>(p.findAllIn(x).mkString(""),1)).groupBy(_._1).mapValues(_.size).toArray.sortWith(_._2>_._2).slice(0,10)



你可能感兴趣的:(scala)