`
qindongliang1922
  • 浏览: 2147074 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
7265517b-f87e-3137-b62c-5c6e30e26109
证道Lucene4
浏览量:116317
097be4a0-491e-39c0-89ff-3456fadf8262
证道Hadoop
浏览量:124587
41c37529-f6d8-32e4-8563-3b42b2712a50
证道shell编程
浏览量:58449
43832365-bc15-3f5d-b3cd-c9161722a70c
ELK修真
浏览量:70347
社区版块
存档分类
最新评论

在Scala里面如何使用元组

阅读更多


元组在Scala语言中是一种十分重要的数据结构,类似数据库里面的一行记录(row),它可以将不同类型的值组合成一个对象,在实际应用中十分广泛。


先来看一个简单的tuple定义:
````
     val tuple=("张三",25)//定义一个tuple
val (name,age)=("张三",25)//变量绑定模式
````
上面的第二种例子中,可以直接通过name和age来访问单个tuple的元素

例子(1):

一个简单的模式匹配
````
    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):

根据类型匹配
````
    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-scala

例子(3):

变量绑定模式
````
    //定义一个对象元组
    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强大的函数方法,我们可以轻松愉快的处理的各种数据集,感兴趣的小伙伴可以自己尝试一下。




有什么问题可以扫码关注微信公众号:我是攻城师(woshigcs),在后台留言咨询。 技术债不能欠,健康债更不能欠, 求道之路,与君同行。


0
0
分享到:
评论

相关推荐

    Scala映射和元组.md

    Scala映射和元组.md

    头歌Scala中集合的使用

    Scala中集合的使用 大学生 1. List 列表的使用 2. Set 集合的使用 3.Map 映射的使用 4. 元组的使用

    tuplez:Scala元组组成

    Scala和Scala.js中的元组组成。 // tupleN + scalar, scalar + tupleN, tupleN + tupleM, up to Tuple22 " app.tulz " %%% " tuplez-full " % " 0.3.4 " // or // tupleN + scalar, scalar + tupleN, tupleN + ...

    Scala程序设计(第2版)

    22.1 在Scala代码中使用Java名称 430 22.2 Java泛型与Scala泛型 430 22.3 JavaBean的性质 432 22.4 AnyVal类型与Java原生类型 433 22.5 Java代码中的Scala名称 433 22.6 本章回顾与下一章提要 434 ...

    12元组

    Scala中元组是固定数量的元素组合在一起,可以看作一个整体。 元组可以储存任意数据类型;数组只能存固定类型(除非父类可以存其他类型)。 元组是不可变的,最多可以存储22个元组,若多则建议使用集合。 可以使用元组...

    scala从入门到精通技术教学视频

    11,在单例对象中定义方法 12.如何定义程序的主入口 13.定义伴生对象 14.private[this]访问权限 15.apply()方法 16.案例_定义工具类 第七章 继承 00.导学 01.继承入门 02.单例对象的继承 03.方法重写 04....

    Scala学习笔记

    scala 学习笔记 方法 函数 类 对象 特质 推断 注解 编译 隐式转换 尾递归 元组 列表

    Scala快速从入门到神坑

    1. 在Windows操作系统中安装Scala 2. 在Linux操作系统中安装Scala 三、Scala 基础部分 3.1 声明值和变量 3.1.1 val变量 3.1.2 var 变量 3.2 级别数据类型和操作 3.2.1 级别数据类型 3.2.2 操作符 3.3 Range 3.4 打印...

    快学 scala 中文版 带完整目录

    16.5 在属性中使用表达式 264 16.6 特殊节点类型 265 16.7 类XPath表达式 266 16.8 模式匹配 267 16.9 修改元素和属性 268 16.10 XML变换 269 16.11 加载和保存 270 16.12 命名空间 273 练习 275 第17章 ...

    《快学Scala》完整版书籍.rar

    scala基础语法,语法基础,控制结构和函数,scala数组相关操作,映射和元组,类,对象,继承,文件和正则表达式,特质,操作符,高阶函数,集合,样式匹配和样例类。

    03Scala下划线的使用

    1.方法转换为函数 scala&gt; def m(x:Int,y:Int) = x*y m: (x: Int, y: Int)Int scala&gt; val f = m _ f: (Int, Int) =&gt; Int = 2.集合中的每一个元素 ...3.获取元组tuple中的元素 scala&gt; val t = (“hadoo

    AhoCorasick-in-Scala

    获取在您输入的输入字符串中找到的所有关键字的列表 val ahoCorasickConfigTuple = ahoCorasickConfigHelper( " keywords.txt " ) val goToTable = ahoCorasickConfigTuple._1 val outputTable = ...

    产品集合:一个非常简单的强类型scala框架,用于表格数据。 元组的集合。 一个强类型的Scala csv读取器和写入器。 轻量级惯用数据框数据表替代品

    使用SBT: libraryDependencies += "com.github.marklister" %% "product-collections" % "1.4.5"或用于scala-js libraryDependencies += "com.github.marklister" %%% "product-collections" % "1.4.5" #文件 ...

    Disentangle:Scala中的可自定义图算法

    Disentangle的方法与其他图形库的不同之处在于,在可行的情况下都使用Scala的现有集合和元组。 Disentangle仅提供最小的特征和类,并不强迫您使用它们。 例如,Dijkstra的parAllPairsShortestPaths()只需要...

    TuplesInKotlin:广泛的元组库包装针对Kotlin Multiplatform的PairTriple

    此存储库包含一堆文件,这些文件提供了扩展名,以使Tuples易于在任何平台上的Kotlin中使用。 要与Scala或Apache Spark一起使用,请参见 。 如何安装 去做 包装Kotlin对和三重 该库将Kotlin的Pair和Triple类型别名...

    scala中的数据结构

    scala的数据结构有:数组Array、元组Tuple、容器Collection、序列Sequence、集合Set、映射Map、迭代器Iterator 2、数组 创建方式 (创建一个长度为10类型为Int的数组 1 val arr = new Array[Int](10) 默认初始化为0 2...

    Scala基础(8)函数定义

    字面量包括整数字面量、浮点数字字面量、布尔型字面量、字符型字面量、字符串字面量和符号字面量、函数字面量和元组字面量。 函数字面量:我们可以像定义变量那样去定义一个函数,由此导致的结果就是函数也会和其他...

    Scala第十章节1

    Scala第十章节章节目标1. 掌握数组, 元组相关知识点2. 掌握列表, 集, 映射相关知识点3. 了解迭代器的用法4. 掌握函数式编程相关知识点5. 掌握学

    scala-fmi-2021

    使用Scala进行高级功能编程 讲课 [] Scala工具 scala , scalac ,REPL sbt,配置,编译,启动和测试 添加库 类型和文字 定义val , var , def , type ,函数。 类型推断 文件和包 值作为对象(带有方法) if...

    avrotuples:Avro Scala帮助程序类

    阿夫罗·塔普尔斯 提供Tuple1到Tuple22 ,允许程序员将固定数量的项目保存在一起,以便它们可以作为单个对象传递。 虽然Array中的所有元素都具有相同的类型,但是TupleN可以具有... 使用Avro元组的相同代码看起来像..

Global site tag (gtag.js) - Google Analytics