大数据之脚踏实地学16--Scala列表、元组与映射

往期回顾

大数据之脚踏实地学15--Scala的数组操作

前言

在上一期的《大数据之脚踏实地学15--Scala的数组操作》分享中,介绍了Scala的数组相关知识,借助于Array函数可以构造定长数组(即数组一旦定义好长度,就无法对元素个数做影响),而通过ArrayBuffer函数则可以构造变长数组。在本期中将介绍Scala的其他常用的数据结构,包括列表、元组和映射。

列表

Scala中的列表与之前分享的数组有一些相似之处,例如列表中的元素也需要具有相同的数据类型、对于不可变列表而言,其长度也是固定的。但也有一些差异,例如对于不可变数组的创建,需要提前指定数组元素的长度,而不可变列表无需指定长度便可直接构造、数组属于可变对象(即数组的元素可以被修改),而列表不是可变对象。接下来通过一些简单的实例,来接受列表的相关知识点。

列表的构造

不可变列表的构造只需要使用List函数就可以轻松搞定,一旦构造好后,其元素便不可以变动,包括列表元素的增加、删除和修改。当然,如果工作中需要对列表元素进行修改,可以构造可变列表,使用ListBuffer函数即可,该函数需要导入scala.collection.mutable模块

// 构造不可变列表
val ls1 = List("apple","orange","banana","dog","cat","monkey","pig")
val ls2 = List(10,22,16,4,8)

// 构造可变列表
import scala.collection.mutable
var ls3 = mutable.ListBuffer(1,1,2,3,5,8,13)

首先介绍一下可变列表的增删改操作,然后再介绍可变列表与不可以列表都可以使用的一些常规方法。

列表的增删改操作

可变列表的增 对于可变列表而言,可以借助于append方法在列表的末尾增加一个或多个元素;使用+=方法在末尾增加一个元素;使用++=方法追加另一个列表;使用insert方法在列表的指定位置增加一个元素。

// 列表元素的增加
ls3.append(21,36) // 增加多个元素
println("ls3 = " + ls3)
ls3.+=(57) // 增加一个元素
println("ls3 = " + ls3)
ls3.++=(ls2) // 将一个列表添加到可变列表中
println("ls3 = " + ls3)
ls3.insert(3,100) // 在指定位置插入元素
println("ls3 = " + ls3)

// 结果输出
ls3 = ListBuffer(1, 1, 2, 3, 5, 8, 13, 21, 36)
ls3 = ListBuffer(1, 1, 2, 3, 5, 8, 13, 21, 36, 57)
ls3 = ListBuffer(1, 1, 2, 3, 5, 8, 13, 21, 36, 57, 10, 22, 16, 4, 8)
ls3 = ListBuffer(1, 1, 2, 100, 3, 5, 8, 13, 21, 36, 57, 10, 22, 16, 4, 8)

可变列表的删 对于列表元素的删除也有一些基本的方法,例如trimStart方法删除列表开头的几个元素;trimEnd则可以删除列表末尾的几个元素;-=方法则可以删除指定的列表元素;clear方法还可以对列表元素做清空处理。

// 列表元素的删除
ls3.trimStart(2) // 删除列表开头的两个元素
println("ls3 = " + ls3)
ls3.trimEnd(2) // 删除列表结尾的两个元素
println("ls3 = " + ls3)
ls3.-=(2,22) // 删除指定的值
println("ls3 = " + ls3)

// 结果输出
ls3 = ListBuffer(2, 100, 3, 5, 8, 13, 21, 36, 57, 10, 22, 16, 4, 8)
ls3 = ListBuffer(2, 100, 3, 5, 8, 13, 21, 36, 57, 10, 22, 16)
ls3 = ListBuffer(100, 3, 5, 8, 13, 21, 36, 57, 10, 16)

可变列表的改 如果工作中设计到可变列表元素的修改时,便可以借助于“取而代之”的思想实现元素之的修改。具体操作如下:

// 列表元素的修改
ls3(8) = 900 // 将第9个元素改为900
println("ls3 = " + ls3)
ls3.update(4,400) // 将第5个元素改为400
println("ls3 = " + ls3)

// 结果输出
ls3 = ListBuffer(100, 3, 5, 8, 400, 21, 36, 57, 10, 16)
ls3 = ListBuffer(100, 3, 5, 8, 400, 21, 36, 57, 900, 16)

列表的其他操作

尽管不可变列表存在一些缺陷,但这不代表它只是一个容器,它还可以做其他事。接下来所要介绍的内容不局限于不可变列表,可变列表也具有相同的操作权限。具体代码案例如下:

// 列表元素的查询
println("列表ls1的第3个元素是:" + ls1(2))
println("列表ls3元素的切片(第4个至第8个元素):" + ls3.slice(3,8))
println("根据条件筛选列表ls2的元素:" + ls2.filter(_>=10))

// 列表元素的删除 -- 需要注意的是,如下方法均不可以之间改变列表本身
println("删除列表前两个元素:" + ls2.drop(2))
println("删除列表后两个元素:" + ls2.dropRight(2))
// dropWhile:从左向右丢弃元素,直到条件不成立
println("删除首批大于等于10的元素:" + ls2.dropWhile(_ >= 10))


// 列表的属性
println("列表ls1的元素个数为:" + ls1.length)
println("列表ls3中偶数的个数:" + ls3.count(_ % 2 == 0))
println("列表ls2元素的排序:" + ls2.sorted) // 如需降序,再使用reverse方法
println("返回列表ls2中首次大于12的元素:" + ls2.find(_ > 12))
// indexOf方法如果找不到元素的位置则返回-1
println("返回ls2中元素值为12的首次位置:" + ls2.indexOf(12))

/* 常规统计函数的属于
ls2.length -- 计数
ls2.sum -- 求和
ls2.min -- 最小值
ls2.max -- 最大值
*/

// 列表ls3与ls2的差集
println("差集为:" + ls3.diff(ls2))

// 列表元素的拼接,结果为字符型对象
println("列表元素的拼接:" + ls2.mkString(","))

// 结果输出
列表ls1的第3个元素是:banana
列表ls3元素的切片(第4个至第8个元素):ListBuffer(8, 400, 21, 36, 57)
根据条件筛选列表ls2的元素:List(10, 22, 16)

ls2 = List(10, 22, 16, 4, 8)
删除列表前两个元素:List(16, 4, 8)
删除列表后两个元素:List(10, 22, 16)
删除首批大于等于10的元素:List(4, 8)

列表ls1的元素个数为:7
列表ls3中偶数的个数:6
列表ls2元素的排序:List(4, 8, 10, 16, 22)
返回ls2中首次大于12的元素:Some(22)
返回ls2中元素值为12的首次位置:-1

差集为:ListBuffer(100, 3, 5, 400, 21, 36, 57, 900)
列表元素的拼接:10,22,16,4,8

元组的构造

元组与列表类似,同样属于不可变对象,所不同的是,列表中的元素是同类型的,元组的元素可以是不同类型的。而且还有一个非常大的区别,列表元素的索引从0开始,而元组则是从1开始,并且两种数据结构的索引写法也不相同。

// 元组的构造--使用一对圆括号即可
val t1 = (1,"First",5.5,"Monday",false,'A',100002345)
// 元组元素的获取
println("元组的第三个元素:" + t1._3)

// 结果输出
元组的第三个元素:5.5

相比于列表而言,元组可用的方法就少了很多,例如length方法、filter方法、drop方法、count方法等。如果你想使用列表的那些常规方法,也是可以的,那就对元组再使用productIterator方法,便可以基于此使用列表的其他方法了。

println("删除开头的两个元素:" )
t1.productIterator.drop(2).foreach(println)

// 结果输出
删除开头的两个元素:
5.5
Monday
false
A
100002345

映射的构造

映射与Python的字典类似,映射的元素是由一对键值对构成的,映射也分为不可变映射和可变映射。借助于Map函数构造不可变映射,元素可以写成key -> value的形式,也可以写成(key,value)的形式。

// 不可变映射
val info = Map("name" -> "Snake", "gender" -> "男", "age" -> 30, ("height",170), "score" -> 88)

// 可变映射
var RFM = mutable.Map("Recency" -> 37, ("Frequency",8), "Money" -> 3274)

可变映射的增删改

// 元素的增加
RFM.+=(("Uid" -> 213244532))
println("RFM = " + RFM)

// 元素的删除
RFM.-=("Frequency")
println("RFM = " + RFM)

// 元素的修改
RFM("Money") = 3330
RFM.update("Recency", 307)
println("RFM = " + RFM)

// 结果输出
RFM = Map(Frequency -> 8, Money -> 3274, Uid -> 213244532, Recency -> 37)
RFM = Map(Money -> 3274, Uid -> 213244532, Recency -> 37)
RFM = Map(Money -> 3330, Uid -> 213244532, Recency -> 307)

映射的其他常用方法

// 映射元素的查询
println("info中name键对应的值:" + info("name"))
println("info中score键对应的值:" + info.get("score"))

// 返回映射的键、值、键值对
println("映射的键为:" + info.keySet)
println("映射的值为:" + info.values)
println("映射的键值对为:" + info.toList)

// 结果输出
info中name键对应的值:Snake
info中score键对应的值:Some(88)
映射的键为:Set(name, score, height, age, gender)
映射的值为:MapLike.DefaultValuesIterable(Snake, 88, 170, 30, 男)
映射的键值对为:List((name,Snake), (score,88), (height,170), (age,30), (gender,男))
结语

本期的内容就介绍到这里,如果你有任何问题,欢迎在公众号的留言区域表达你的疑问。同时,也欢迎各位朋友继续转发与分享文中的内容,让更多的人学习和进步。

每天进步一点点:数据分析1480

长按扫码关注我

本文分享自微信公众号 - 数据分析1480(lsxxx2011)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-03-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券