此代碼僅供學習參考,若有理解錯誤的地方請及時聯繫博主,謝謝。
package FileIO
import scala.io.Source;
import scala.util.matching.Regex
object WordIO {
def main(args: Array[String]) {
val Sit = Source.fromFile("D://cc.txt").getLines() // 文件讀取,按行
val word = Sit.flatMap { line => line.split(" ") } // 分離word
val wordregex = word.flatMap(str => stringregex(str))
val group = wordregex.foldLeft(Map.empty[String, Int]) { // 向左摺疊 def foldLeft[B](z: B)(op: (B, A) => B): B = { A的類型其實就是調用這個函數的類型this.seq
(kv, str) => kv + (str -> (kv.getOrElse(str, 0) + 1)) // 初始化一個要得到的類型B(Map[String,Int]) 由A和B進過op,就是操作最終生成B(第一步是Empty的Map放入一個str和0+1,第二步傳入的是第一步產生的Map及wordregex中第二個值,進行if else)
} // map中的ifelse操作 Map[String,Int](也就是kv)中存在str則用str的值+1,若沒有就用0+1
for(kv <-group){println(kv)}
}
def stringregex (str: String) : List[String] = {
val pattern = new Regex("[a-zA-Z]*['|’]?[a-zA-Z]*"); // 排除,."“” 但要保留’'等,使統計更精確
val string = (pattern findAllIn(str)).mkString("")
return List(string)
}
}
對於flatLeft()函數的解釋:
def foldLeft[B](z: B)(op: (B, A) => B): B = {
var result = z
this.seq foreach (x => result = op(result, x))
result
}
此方法接受2個參數,z和op,一個是B類型的參數,一個是返回B類型的函數。
在看到這個trait其實是TraversableOnce,可迭代的集合。
def seq: TraversableOnce[A]
比如一個val listA = List(1,2,3)
listA其實是實現了TraversableOnce這個trait的。
我們可以直接使用:
[java] view plain copy
scala> listA.foldLeft(0)((sum,i)=>sum+i)
res26: Int = 6
這個裏面的0其實就是z返回值是Int類型即B類型
那麼可以看出op這個函數返回值也需要是Int類型
可以看出
val result = z, 這裏其實就是0,x=>result=op(result, x) , sum其實也是z
其實z就是返回值,this.seq在這裏就是list,對list遍歷,這裏執行op函數。
這裏我們執行的是sum+i,就是累加了1+2+3=6
對於getOrElse()函數的解釋:
Map中的if()else()操作的變型
在Spark中寫法是:persons.getOrElse("Spark",1000) //如果persons這個Map中包含有Spark,取出它的值,如果沒有,值就是1000。
for循環訪問persons裏面的Key和value
for((key,value)<- persons)
println(key+":"+value)
值:Hadoop:11
Spark:6
函數參考來源: