元組在Scala語言中是一種十分重要的數據結構,相似數據庫裏面的一行記錄(row),它能夠將不一樣類型的值組合成一個對象,在實際應用中十分普遍。vue
先來看一個簡單的tuple定義:java
val tuple=("張三",25)//定義一個tuple val (name,age)=("張三",25)//變量綁定模式
上面的第二種例子中,能夠直接經過name和age來訪問單個tuple的元素數據庫
例子(1):數據結構
一個簡單的模式匹配elasticsearch
val tuple=(1,2,3,4) def tupleMatch(x:Any)=x match { case (first,second)=> println(s"第一個元素:${first} 第二個元素:${second}") case (first,_,three,_)=> println(s"第一個元素:${first} 第三個元素:${three}") case _=> println("沒有任何匹配") } tupleMatch(tuple)//匹配上面的第二個
例子(2):函數
根據類型匹配oop
def typeMatch(x:Any)=x match { case x:String=> println("string") case x:Int=> println("int") case x:Boolean=>println("boolean") case _=> println("其餘") } typeMatch("x")
注意上面的代碼裏面case後面的若是有List[String]類型的,最好用一個類封裝起來在作匹配,不然會出錯。具體的方式請參考: https://www.cakesolutions.net/teamblogs/ways-to-pattern-match-generic-types-in-scalaspa
例子(3):.net
變量綁定模式scala
//定義一個對象元組 case class Dog(val name:String,val age:Int) val dog=Dog("Pet",2) def patternMatch(x:Any)=x match { case d@Dog(_,_)=>println("變量值:"+d.name) case _=> println("默認") } patternMatch(dog)//Pet
注意普通的類不能直接使用上面的模式匹配
例子(4):
for循環的使用元組進行的模式匹配
val map= Map("java"->"Hadoop","js"->"vue","scala"->"spark") //1,變量模式匹配 for( (k,v)<-map ){ println(k,v) } println("====================") //2,常量模式匹配,第二個值必須是spark,纔會打印出來 for( (k,e@"spark")<-map ){ println(k,e) } println("====================") //3,類型匹配模式,注意elasticsearch是不會被打印出來的 for( (k,v:String)<- Map("java"->"Hadoop","js"->"vue","scala"->"spark", "elasticsearch"->"java".size) ){ println(k,v) } println("====================") //4,構造函數模式匹配 case class Dog(val name:String,val age:Int) for(Dog(name,age)<-List(Dog("pet",2),Dog("penny",3),Dog("digo",4) ) ){ println(s"Dog ${name} is ${age} years old") } println("====================") //5,序列模式匹配 for( List(first,_*)<- List( List(1,2,3),List(4,5,6,7) ) ){ println(s"${first}") } println("====================") //6,變量綁定的另外一種模式 val list2=List( List(1,2,3),List(4,5,6,7)) def list2Match(x:AnyRef)=x match { case List(first,e@List(4,_*)) => println(e) case _=> println("defalult") } list2Match(list2)
結果:
(java,Hadoop) (js,vue) (scala,spark) ==================== (scala,spark) ==================== (java,Hadoop) (js,vue) (scala,spark) ==================== Dog pet is 2 years old Dog penny is 3 years old Dog digo is 4 years old ==================== 1 4 ==================== List(4, 5, 6, 7)
最後咱們使用元組,來模擬一個相似下面的SQL的例子:
表(pet)結構:
name(string),ct(int) cat,2 cat,6 cat,2 dog,1 dog,2
統計語句:
select name ,sum(ct) as c,count(*),max(ct),min(ct) from pet group by name order by c desc
Scala代碼以下:
val list = ArrayBuffer[(String, Int)]() list += (("cat", 2)) list += (("cat", 6)) list += (("cat", 2)) list += (("dog", 1)) list += (("dog", 2)) println("寵物名,數量") //使用打印全部的數據 for ((name, count) <- list) { println(name, count) } println("=================================") //求出,按寵物名分組,出現數量和,出現總次數,最大數量,最小數量,並按照總次數降序排序 val result = list.groupBy(_._1).map { case (key,valueList) => { val sum = valueList.map(_._2).sum//求valueList出現次數的總和 val maxCount = valueList.max._2//最大次數 val minCount = valueList.min._2//最小次數 (key -> (sum, valueList.size, maxCount, minCount))//以Map的結果返回 } }.toSeq.sortWith(_._2._1 > _._2._1) //轉化成Seq後才能進行排序操做,至關於取的是_._2表明的是value的值, //繼續_1表明的是取裏面的sum進行降序排序,若是是<號,則是升序排 //使用元組遍歷最終結果 println("寵物名,出現數量和,出現總次數,最大數量,最小數量") for( (name,(sum,size,maxCount,minCount)) <-result ){ println(name,sum,size,maxCount,minCount) }
其實,核心代碼只有中間的這一部分:
val result = list.groupBy(_._1).map {//分組處理 case (key,valueList) => { val sum = valueList.map(_._2).sum//求valueList出現次數的總和 val maxCount = valueList.max._2//最大次數 val minCount = valueList.min._2//最小次數 (key -> (sum, valueList.size, maxCount, minCount))//以Map的結果返回 } }.toSeq.sortWith(_._2._1 > _._2._1)//降序排
最終結果:
寵物名,數量 (cat,2) (cat,6) (cat,2) (dog,1) (dog,2) ================================= 寵物名,出現數量和,出現總次數,最大數量,最小數量 (cat,10,3,6,2) (dog,3,2,2,1)
簡單解釋一下核心部分的代碼含義:
首先執行了一個groupBy函數,對元組裏面的第一個元素也就是寵物名進行 分組,分組以後,每一個寵物名同樣的數據會聚合在一塊兒,而後執行一個map函數,對裏面的valueList進行各類運算,得出來咱們 須要的結果後,最終再以Map的數據結構返回,由於Map自己是無法排序的,因此咱們得先須要轉成Seq類型,最後再執行sortWith方法對value裏面的最大次數進行降序排,若是是升序排,只須要把大於號該成小於號便可。
總結:
本篇主要介紹了tuple幾種常見的應用場景,經過使用tuple數據結構配合上scala強大的函數方法,咱們能夠輕鬆愉快的處理的各類數據集,感興趣的小夥伴能夠本身嘗試一下。