快学Scala-第三章 数组相关操作
知识点:
1.定长数组 Array
val nums = new Array[Int](10) //10个整数的数组,所有元素初始化为0
val a = new Array[String](10) //10个元素的字符串数组,所有元素初始化为null
val s= Array("Hello","World") //长度为2的Array(String) 类型是编译器推断出来的,已提供初始值就不需要new
s(0) = "Goodbye" //Array("Google","World") 使用()而不是[]来访问元素
Scala的Array以Java数组方式实现,例子中的s对应的是java.lang.String[]
2.变长数组:数组缓冲 ArrayBuffer
对于长度按需要变化的数组,Java-ArrayList || C++-vector || Scala-ArrayBuffer
val b = ArrayBuffer[Int]() //或者 new ArrayBuffer[Int]
b += 1 //ArrayBuffer(1) 用 += 在尾端添加元素
b += (1,2,3,4,5) //ArrayBuffer(1,1,2,3,4,5) 在尾端添加多个元素,用括号包起来
b ++= Array(6,7,8) //ArrayBuffer(1,1,2,3,4,5,6,7,8) 用 ++= 追加任何集合
b.trimEnd(5) //ArrayBuffer(1,1,2,3)移除最后5个元素
在数组缓冲的尾部添加或移除元素是一个高效的操作。也可以在任意位置插入和删除元素,这样的操作不高效,引发位置后的元素都必须被平移。
b.insert(2, 9) //ArrayBuffer(1,1,9,2,3)
b.insert(2, 10,11) //ArrayBuffer(1,1,10,11,9,2,3)
b.remove(2) //ArrayBuffer(1,1,11,9,2,3)
b.remove(2,3) //ArrayBuffer(1,1,3)
有时候你需要构建一个Array,但不知道元素有多少个,可以先构建ArrayBuffer,再调用b.toArray();反过来,调用a.toBuffer可以将一个数组a转换为一个数组缓冲。
3.遍历数组和数组缓冲
for(i <- 0 until a.length) //变量i值从0取到a.length-1
println(i + ": " + a(i))
for(i <- 区间) 会让i遍历区间所有值。
0 until (a.length, 2)
//Range(0,2,4,6,...) 每两个元素一跳 (0 until a.length).reverse
//Range(...,3,2,1,0) 逆序 for(elem <- a) //不使用数组下标时
println(elem)
3.数组转换
val aa = Array(2,5,8,9)
val result = for(elem <- aa) yield 2 * elem
//result是Array(4,10,16,18)
for(…) yield 循环创建了一个类型与原始集合相同的新集合。结果包含yield之后的表达式,每次迭代对应一个。当你遍历一个集合时,你只想处理那些满足特定条件的元素,可以通过 守卫 :for 中的 if 实现。
for(elem <- aa if elem % 2 == 0) yield 2 * elem
//另一种实现方法
a.filter(_ % 2 == 0).map(2 * _)
a.filter{ _ % 2 == 0} map { 2 * _}
4.常用方法
sum\max\sorted sum方法的数组元素类型必须是数值类型,sorted方法将数组或缓冲数组排序后返回经过排序的数组或缓冲数组,不修改原始版本。
显示数组或缓冲数组的内容,可以用mkString方法。
5.多维数组是通过数组的数组实现的
val matrix = Array.ofDim[Double](3,4)
matrix(row)(column) = 42
//创建不规则的数组
val triangle = new Array[Array[Int]](10)
for(i <- 0 until triangle.length)
triangle(i) = new Array[Int](i+1)
练习:(答案源链接)
1.编写一段代码,将a设置为一个n个随机整数的数组,要求随机数介于0(包含)和n(不包含)之间
class test{
def main(args:Array[Int]){
getArr(10).foreach(println)
} def getArr(n:Int): Array[Int] = {
val a = new Array[Int](n)
val rand = new scala.util.Random()
for(i <- a) yield rand.nextInt()
} }
2.编写一个循环,将整数数组中相邻的元素置换
class test{
def main(args:Array[Int]){
val arr = Array(1,2,3,4,5)
revert(arr)
arr.foreach(println)
} def revert(a:Array[Int]) = {
for(i <- 0 until (a.length - 1,2)){
val t = a(i)
a(i) = a(i+1)
a(i+1) = t
}
}
}
3.重复前一个练习,不过这次生成一个新的值交换过的数组。用for/yield。
class test{
def main(args:Array[Int]){
val a = Array(1,2,3,4,5)
val b = revertYield(a)
b.foreach(println)
} def revertYield(a:Array[Int]) = {
for(i <- 0 until a.length) yield {
if( i < (a.length - 1) && i % 2 == 0){
//偶数下标时,则交换下一个相邻的元素值
val t = a(i)
a(i) = a(i+1)
a(i+1) = t
}
a(i) //因为生成新的数组,每一个元素都要返回
}
}
}
4.给定一个整数数组,产出一个新的数组,包含元数组中的所有正值,以原有顺序排列,之后的元素是所有零或负值,以原有顺序排列。
import scala.collection.mutable.ArrayBuffer class test{
def main(args:Array[Int]){
val a = Array(1,-2,0,4,5,0,-3)
val b = reCombine(a)
b.foreach(println)
} def reCombine(a:Array[Int]) = {
val buf = new ArrayBuffer[Int]();
buf ++= (for( i <- a if(i > 0)) yield i)
buf ++= (for( i <- a if(i == 0 || i < 0)) yield i)
buf.toArray
}
}
5.如何计算Array[Double]的平均值?
class test{
def main(args:Array[Int]){
val a = Array(1.0,5.6,0.0,-3.0)
val b = average(a)
println(b)
} def average(a:Array[Double]) = {
var t = 0.0
for(i <- a){
t += i
}
t/a.length
} def ave(a:Array[Double]) = {
a.sum / a.length
}
}
6.如何重新组织Array[Int]的元素将它们反序排列?对于ArrayBuffer[Int]你又会怎么做呢?
import scala.collection.mutable.ArrayBuffer object Hello {
def main(args: Array[String]) {
val a = Array(1,2,3,4,5)
reverseArray(a)
println("array reverse:")
a.foreach(println)
val b = a.reverse //将a的值逆序回去了
b.foreach(println) println("bufferArray reverse:")
val c = ArrayBuffer(6,7,8,9,0);
val d = c.reverse
d.foreach(println)
}
def reverseArray(a:Array[Int]) = {
for( i <- 0 until (a.length / 2)){
val t = a(i)
a(i) = a(a.length-1-i)
a(a.length-1-i)=t
}
}
}
7.编写一段代码,产出数组中的所有值,去掉重复项
import scala.collection.mutable.ArrayBuffer object Hello {
def main(args: Array[String]) {
val ab = new ArrayBuffer[Int]()
val c = new ArrayBuffer[Int]()
println("Input the array line,separated by a space,ended with an enter.")
val input = readLine().toString().split(' ');
for(i <- input){
ab += i.toInt
}
// ab.foreach(println)
c ++= ab.distinct
c.foreach(println)
}
}
8.重新编写3.4节结尾的示例。收集负值元素的下标,反序,去掉最后一个下标,然后对每一个下标调用a.remove(i)。比较这样做的效率和3.4节中另外两种方法的效率
import scala.collection.mutable.ArrayBuffer object Hello {
def main(args: Array[String]) {
val a = ArrayBuffer(1,2,4,-2,0,-1,-4,8)
deleteNeg(a)
a.foreach(println)
}
def deleteNeg(a:ArrayBuffer[Int]) = {
val indexes = for(i <- 0 until a.length if a(i) < 0 ) yield i
//不能val b = indexex.reverse.trimEnd(1) reverse后,它是一个Seq序列。
//value trimEnd is not a member of scala.collection.immutable.IndexedSeq[Int]
val b = new ArrayBuffer[Int]()
b ++= indexes.reverse
b.trimEnd(1)
//remove是ArrayBuffer的函数,如果传入的是Array,则需要调用toBuffer
for(i <- b){
a.remove(i)
}
}
}
9.创建一个由java.util.TimeZone.getAvailableIDs返回的时区集合,判断条件是它们在美洲,去掉”America/“前缀并排序。
import scala.collection.mutable.ArrayBuffer
import scala.collection.JavaConversions.asScalaBuffer object Hello
{
def main(args: Array[String]) = {
var c = timeZoneName()
c.foreach(println)
} def timeZoneName() = {
val arr = java.util.TimeZone.getAvailableIDs();
val tmp = (for (i <- arr if i.startsWith("America/")) yield {
i.drop("America/".length)
})
scala.util.Sorting.quickSort(tmp)
tmp
}
}
10.引入java.awt.datatransfer._并构建一个类型为SystemFlavorMap类型的对象,然后以DataFlavor.imageFlavor为参数调用getNativesForFlavor方法,以Scala缓冲保存返回值。
import scala.collection.JavaConversions.asScalaBuffer
import scala.collection.mutable.Buffer
import java.awt.datatransfer._ object Hello
{
def main(args: Array[String]) = {
val flavors = SystemFlavorMap.getDefaultFlavorMap().asInstanceOf[SystemFlavorMap]
val buf : Buffer[String] = flavors.getNativesForFlavor(DataFlavor.imageFlavor);
buf.foreach(println);
}
}
快学Scala-第三章 数组相关操作的更多相关文章
- 快学Scala习题解答—第三章 数组相关操作
3 数组相关操作 3.1 编写一段代码.将a设置为一个n个随机整数的数组,要求随机数介于0(包括)和n(不包括)之间 random和yield的使用 import scala.math.rando ...
- 《快学Scala》第三章 数组相关操作
- 快学Scala 第三课 (定长数组,变长数组, 数组循环, 数组转换, 数组常用操作)
定长数组定义: val ar = new Array[Int](10) val arr = Array("aa", "bb") 定长数组赋值: arr(0) = ...
- 快学Scala 第6章 对象 - 练习
1. 编写一个Conversions对象,加入inchesToCentimeters.gallonsToLiters和milesToKilometers方法. object Conversions { ...
- 《快学Scala》第二章 控制结构和函数
- 《快学Scala》第一章 基础
- 快学Scala习题解答—第一章 基础
1 简介 近期对Scala比较感兴趣,买了本<快学Scala>,感觉不错.比<Programming Scala:Tackle Multi-Core Complexity on th ...
- Scala学习(三)----数组相关操作
数组相关操作 摘要: 本篇主要学习如何在Scala中操作数组.Java和C++程序员通常会选用数组或近似的结构(比如数组列表或向量)来收集一组元素.在Scala中,我们的选择更多,不过现在我们先假定不 ...
- [Scala] 快学Scala A1L1
基础 1.1 声明值和变量 在Scala中,鼓励使用val; 不需要给出值或变量的类型,这个信息可以从初始化表达式推断出来.在必要的时候,可以指定类型. 在Scala中,仅当同一行代码中存在多条语句时 ...
随机推荐
- LNK2019解决思路
虽然官网给出了很多可能的原因,最可能的原因还是因为缺少某个库文件.最近解决的一个为例总结一下思路 Winmm.lib; ad_win32.obj : error LNK2019: unresolved ...
- chapter11_2 Lua链表与队列
链表 由于table是动态的实体,所以在Lua中实现链表是很方便的.每个节点以一个table来表示,一个“链表”只是节点table中的一个字段. 该字段包含了对其他table的引用.例如,要实现一个基 ...
- Rational Rose 2003 逆向工程转换C++ / VC++ 6.0源代码成UML类图
目录 1.安装&破解Rational Rose 2003 1.1 安装Rose 2003 1.2 破解Rose 2003 1.3运行出错“没有找到suite objects.dl” 2. Ra ...
- 洛谷-生活大爆炸版石头剪刀布-NOIP2014提高组复赛
题目描述 Description 石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头.如果两个人出拳一样,则不分胜负.在<生活大爆炸>第二季第8 集中出现了一种石头剪刀布的升级版 ...
- 关于maven相互依赖的工程部署问题
环境:win7 64位,myeclipse10.6,eclipse4.5,都配置了svn插件 问题描述:1.工程模块化之后都是通过pom配置model来关联的,svn提交之后,通过myeclipse的 ...
- Core Animation中的组动画
实际开发中一个物体的运动往往是复合运动,单一属性的运动情况比较少,但恰恰属性动画每次进行动画设置时一次只能设置一个属性进行动画控制(不管是 基础动画还是关键帧动画都是如此),这样一来要做一个复合运动的 ...
- C++ : 从栈和堆来理解C#中的值类型和引用类型
C++中并没有值类型和引用类型之说,标准变量或者自定义对象的存取默认是没有区别的.但如果深入地来看,就要了解C++中,管理数据的两大内存区域:栈和堆. 栈(stack)是类似于一个先进后出的抽屉.它的 ...
- CentOS挂载硬盘
1.查看当前硬盘使用状况: [root@gluster_node1 ~]# df -h 文件系统 容量 已用 可用 已用%% 挂载点 /dev/sda3 14G 2.4G 11G 19% / ...
- 交互式shell和非交互式shell的区别
交互式模式就是shell等待你的输入,并且执行你提交的命令.这种模式被称作交互式是因为shell与用户进行交互.这种模式也是大多数用户非常熟悉的:登录.执行一些命令.签退.当你签退后,shell也终止 ...
- PureMVC 框架总结收录
PureMVC框架的目标很明确,就是把程序分为低耦合的三层:Model.View和Controller. 通过使用PureMVC后,我们的代码将集中分为以下几个部分:Façade.Command.Me ...