元组在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强大的函数方法,咱们能够轻松愉快的处理的各类数据集,感兴趣的小伙伴能够本身尝试一下。