在Scala裏面如何使用元組

元組在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強大的函數方法,咱們能夠輕鬆愉快的處理的各類數據集,感興趣的小夥伴能夠本身嘗試一下。

相關文章
相關標籤/搜索