集合

集合的定义

Swift中提供了两种数据结构用于存放数据的集合,各自是数组(Array)和字典(Dictionary)。

他们的主要差别在于数组中的元素由下标确定。而字典中的数据的值由数据的键(Key)决定。下面我们觉得集合就是数组或字典。

集合的可变性

我们能够定义一个集合常量或者集合变量。

一旦定义为常量,就意味着集合的长度、内容和顺序都不能再改动了。比方,定义为常量的数组,不能再向当中加入新的元素。

数组的创建

由于swift中变量的创建遵循“ var 变量名:变量类型 ”的语法。因此数组的创建归根结底还是数组类型的定义。

一共同拥有三种方法来定义数组的类型:

var arrayOne:Array<Int> = [1,2,3]
println("arrayLong = \(arrayOne)") var arrayTwo:[Int] = [1,2,3]
println("arrayShort = \(arrayTwo)") var arrayThree = [1,2,3]
println("arrayThree = \(arrayThree)")

第一种是数组类型的完整定义,即Array关键字加上一对尖括号,括号内写上数组元素的类型。

另外一种是数组类型的简化定义,即一对方括号内写上数组元素的类型。这与第一种定义方法全然等价。

在使用这两种方法定义数组的时候。一定要确保数组中每一个元素类型同样,否则将会产生编译错误。

第三种运用了Swift的类型推导的特性。须要注意的是。数组的值由方括号组成,里面的元素用逗号隔开。假设方括号改成了圆括号。编译器不会报错(这将变成元组),所以千万要小心,避免莫名其妙的错误。

第三种方法除了书写简单之外,另一种优点,即不必确保数组中每一个元素类型同样。我们来通过代码看一看多个不同类型的元素出如今统一数组中会发生什么情况:

var arrayThree = [1,2,3]
println("arrayThree = \(arrayThree)") var arrayMixed = [1,"abc",true, 1.5]
println("arrayMixed = \(arrayMixed)")//在这一行结束前设置断点
//在LLDB调试当中分别输入print arrayThree和print arrayMixed

能够得到例如以下结果

([Int]) $R0 = 3 values {
[0] = 1
[1] = 2
[2] = 3
} ([NSObject]) $R1 = 4 values {
[0] = 0x0000000000000137 Int64(1)
[1] = "abc"
[2] = 0x00007fff7255e8a8 {
NSNumber = {
NSValue = (null)
}
}
[3] = 0x00000001006008a0 {
NSNumber = {
NSValue = (null)
}
}
}

因此不难发现,arrayMixed数组之所以能够加入多个类型的元素,是由于它被推导为Array< NSObject>类型。同样的,所以一旦数组的类型确定。就不能再插入不属于这个类型的的值。

在我阅读的教材上,作者特别提出。不指定类型的数组不能使用Array的append方法。

可是经过我的測试。并没有这种限制。有兴趣的读者能够自行測试,欢迎指正。

数组的訪问与改动

数组长度

能够使用数组的仅仅读属性count来获取数组长度:

var arrayThree = [1,2,3]
println("arrayThree.count = \(arrayThree.count)")

推断数组为空

能够使用数组的仅仅读属性isEmpty来推断数组是否为空。当然通过推断count是否为0也能够达到同样的效果,只是代码略长一些。

var arrayThree = [1,2,3]
if !arrayThree.isEmpty{
println("Array Three is not empty")
}

加入新元素

一共同拥有两种方法能够在数组的尾部加入新元素:

//方法一,使用数组的append函数
var arrayThree = [1,2,3]
arrayThree.append(4)
println("arrayThree = \(arrayThree)") //方法二。使用加法运算符
var arrayThree = [1,2,3]
arrayThree += [4]
println("arrayThree = \(arrayThree)")

不管使用哪种方法,都必须保证新加入的元素和数组类型同样。

比方试图像arrayThree中加入元素’1.5’会导致编译错误。

能够看到,另外一种方法的本质实际上是在两个数组对象之间调用加法运算符,得到的结果是两个数组拼接之后的结果。

因此,另外一种方法具有一个强大的功能,即向数组尾部加入多个元素。

另一种通用的方法,即调用数组的insert(atIndex:)方法。在指定位置插入新元素。

var arrayThree = [1,2,3]
arrayThree.insert(4, atIndex: 2)
println("arrayThree = \(arrayThree)")

删除数组元素

能够调用数组的removeAtIndex()和removeLast()方法。

var arrayThree = [1,2,3]
var numberThree = arrayThree.removeAtIndex(2)
var numberTwo = arrayThree.removeLast()

这两个方法会返回被删除的元素的值,当然假设不须要知道,能够无视它的返回值,直接调用方法就可以。

须要注意的一点是,removeAtIndex方法首先要推断下标是否越界。也就是说它会用到数组的长度。这意味着须要线性遍历数组。因此假设仅仅须要移除数组的最后一个元素且数组长度非常大时。应该使用removeLast()方法。

訪问数组元素

了解了怎样加入和删除元素。我们就要想办法把新加入的元素取出来看看了。通过数组下标能够訪问指定位置的数组元素,语法与C语言同样。

var arrayThree = [1,2,3]
println("ArrayThree[2] = \(arrayThree[2])")

改动数组元素

下标不仅能够訪问数组元素。还能够实现数组元素的改动。

这和訪问数组元素是非常相似的,仅仅要交换等号两边变量的位置就可以。

var arrayThree = [1,2,3]
var secondInt = arrayThree[1] //訪问元素 var newSecond = 4
arrayThree[2] = newSecond //改动数组元素

不仅如此,还能够通过数组下标批量改动元素:

var arrayThree = [1,2,3]
var firstNumber = 1
var secondNumber = 2
arrayThree[0...1] = [firstNumber,secondNumber]

此时,等号的右側必须是数组的字面量,而不能是一个数组变量。

也就是说这种写法是错误的:

var arrayThree = [1,2,3]
var newArray = [3,4]
var newSlice: ArraySlice<Int> = [3,4]
arrayThree[0...1] = newArray //错误。 arrayThree[0...1] = newSlice //正确

原因是左边的arrayThree[0…1]事实上是一个SubArray,在Swift中它的类型叫做ArraySlice。即Int类型的数组切片,而右边是一个Array类型变量,依据Swift类型安全的特性,这种操作自然是被禁止的。

假设左边的切片长度和右边的变量长度不一致会发生什么情况呢?不用过于操心,这不会产生不论什么错误。Swift会机智的帮我们解决问题。

var arrayOne:[Int] = [1,2,3]
var arrayTwo = [1,2,3]
var sliceOne:ArraySlice<Int> = [1,2,3]
var sliceTwo:ArraySlice<Int> = [1]
arrayOne[1...2] = sliceOne
arrayTwo[1...2] = sliceTwo
println("arrayOne = \(arrayOne)")
println("arrayTwo = \(arrayTwo)")

输出结果各自是:

arrayOne = [1, 1, 2, 3]
arrayTwo = [1, 1]

因此。假设变量长度超过切片长度,将会自己主动在切片位置后加入元素(如同arrayOne),相当于调用了数组的insert(atIndex:)方法若干次。同样地,假设变量长度少于切片长度,没有值的位置的元素自己主动被移除,后面的元素自己主动向前补上。相当于调用了数组的removeAtIndex()方法若干次。

尽管这样不会出现不论什么错误,只是出于逻辑严谨性考虑,应该避免等号两端变量长度不一样的情况。

数组遍历

之前我们介绍了数组的增删改操作,还缺少一个查找。

也就是数组的遍历。

在Swift中,除了像C语言那样定义一个下标变量,在for循环中遍历数组,还有两种方式遍历数组。

//方法一,使用for in循环高速遍历
var array = [1,2,3,2,1,32,99]
for number in array{
println("number = \(number)")
}

通过观察输出结果能够发现。for in循环是依照从前向后的顺序遍历数组的。

//方法二:使用enumerate函数
var array = [1,2,3,2,1,32,99]
for (index, value) in enumerate(array){
println("value = \(value)")
}

enumerate(array)方法的返回值是一个数组。数组中的每一个元素都是一个二元元组。第一个值是下标index。第二个值是元素的值。这个方案也是顺序遍历数组。

数组的初始化

在本章的开头。我们利用数组字面量来初始化一个数组。事实上,数组还有其它的初始化方法。

首先类比字符串的构造方法var string = String(),我们能够得知数组的另外两种构造方法。

var arrayOne = [Int]()
var arrayTwo = Array<Int>()
println("第一个数组元素个数为:\(arrayOne.count)")
println("第二个数组元素个数为:\(arrayTwo.count)")

执行结果:

第一个数组元素个数为:0
第二个数组元素个数为:0

除此以外,数组另一种特殊的构造方法,能够指定数组长度,在这种情况下还必须强制指定数组中每一个元素的值。

假设觉得无用的话。能够先设置为0,然后再改动。

var arrayThree = [Int](count: 5, repeatedValue: 0)
var arrayFour = Array<Int>(count: 5, repeatedValue: 0)
var arrayFiver = Array(count: 5, repeatedValue: 0)
print("第三个数组为:\(arrayThree)")
print("第四个数组为:\(arrayFour)")
print("第五个数组为:\(arrayFiver)")

得益于类型推导,第五种数组初始化方法也是合法的。

可是之前的标准初始化方法不能够这么简化。输出结果例如以下:

第三个数组为:[0, 0, 0, 0, 0]
第四个数组为:[1, 1, 1, 1, 1]
第五个数组为:[2, 2, 2, 2, 2]

附录

查看完整专栏——《Swift轻松入门》

【Swift入门(一)——基本的语法】

【Swift入门(二)——字符与字符串】

【Swift入门(三)——元组(Tuple)】

【Swift入门(四)——可选类型(Optionals)与断言(Assert)】

【Swift入门(五)——数组(Array)】

【Swift入门(六)——字典(Dictionary)】

【Swift入门(七)——结构体(Struct)】

【Swift入门(八)——功能强大的求余运算符】

【Swift入门(九)——String与Int、Double、Float等数字相互转换】

【Swift入门(十)——循环引用、弱引用和无主引用】

【Swift入门(十一)——类型转换与is、as操作】

【Swift入门(十二)——利用Extension加入逆序输出字符串方法】

Swift入门(五)——数组(Array)的更多相关文章

  1. Javascript入门(五)数组操作、循环语句

    一.数组与数组操作 <script type="text/javascript"> //数组定义方式 var list1 = new Array(1,2,3); var ...

  2. Swift 4.0 数组(Array)之过滤器(filter)的使用

    我们先来定义一个常量整型数组 let array = [5, 4, 3, 1, 2] 过滤器(filter)使用之筛选出大于3的值 let resultArray = array.filter { ( ...

  3. Swift 4.0 数组(Array)学习

    定义数组常量(常量只有读操作) let array1: [Int] = [11, 55, 5] let array2 = [11, 55, 5] 定义数组变量 var array: [Int] = [ ...

  4. Swift语法基础入门二(数组, 字典, 字符串)

    Swift语法基础入门二(数组, 字典, 字符串) 数组(有序数据的集) *格式 : [] / Int / Array() let 不可变数组 var 可变数组 注意: 不需要改变集合的时候创建不可变 ...

  5. [Swift]数组(Array)最强解析

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  6. swift基本用法-数组array

    数组简单用法 //------------------------------------------------------------------------------ // 1. 数组定义 / ...

  7. 学习Swift -- 数组(Array) - 持续更新

    集合类型--数组 Array是Swift中的一种集合类型:数组,数组是使用有序列表储存同一类型的多个值,与OC的NSArray的最大不同是,Swift的数组是值类型,OC的数组是引用类型 声明数组的方 ...

  8. [Swift]JSON字符串与字典(Dictionary)、数组(Array)之间的相互转换

    1.JSON字符串与字典(Dictionary)之间的相互转换 import Foundation //JSON字符串转换为字典(Dictionary) func getDictionaryFromJ ...

  9. Swift入门(一)——基本的语法

    近期開始学习swift.把学习的过程和总结整理成一个系列.方便日后回想总结. 基本的语法 基础语法 swift中每一行结束后不须要加分号.多个语句在同一行内须要用分好隔开 //表示凝视.或者用/* - ...

随机推荐

  1. python链接mysql以及常用语法

    MySQL是一个关系型数据库管理系统 ,其体积小.速度快.总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择 MySQL 作为网站数据库.在使用过程中不总是和它打交道,导致使用时候都得 ...

  2. SignalR实现消息推送,包括私聊、群聊、在线所有人接收消息(源码)

    一.关于SignalR 1.简介:Signal 是微软支持的一个运行在 Dot NET 平台上的 html websocket 框架.它出现的主要目的是实现服务器主动推送(Push)消息到客户端页面, ...

  3. 【WEB API项目实战干货系列】- WEB API入门(一)

    这篇做为这个系列的第一篇,做基本的介绍,有经验的人可以直接跳到第二部分创建 ProductController.   创建 Web API 项目 在这里我们使用VS2013, .NET 4.5.1创建 ...

  4. 轻松驾驭Tomcat

    Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选.对于一个初学者来说,可以这样 ...

  5. Nodejs学习笔记(十五)--- Node.js + Koa2 构建网站简单示例

    目录 前言 搭建项目及其它准备工作 创建数据库 创建Koa2项目 安装项目其它需要包 清除冗余文件并重新规划项目目录 配置文件 规划示例路由,并新建相关文件 实现数据访问和业务逻辑相关方法 编写mys ...

  6. 开篇-我眼中的FPGA

    既然是开篇,那就来闲话叨一叨FPGA吧. 掰掰指头,结识FPGA估计有5年多.作为嵌入式工程师,每天的日常充斥着ARM.DSP.操作系统.通讯.总线等耳熟能详的词汇,徜徉其中不能自拔,而这其中,自觉最 ...

  7. 使用dropwizard(3)-加入DI-dagger2

    前言 习惯了Spring全家桶,对spring的容器爱不释手.使用dropwizard,看起来确实很轻,然而,真正使用的时候不得不面临一个问题.我们不可能一个resource就能把所有的业务逻辑囊括! ...

  8. Java 8的新特性—终极版

    作者:杜琪[译] 原文链接:http://www.jianshu.com/p/5b800057f2d8 1. 简介 毫无疑问,Java 8是Java自Java 5(发布于2004年)之后的最重要的版本 ...

  9. 关于node的前端项目编译时内存溢出问题

    最近在做一个基于vue 的多页面项目  , 页面n++多,编译时发生node内存溢出问题,继而百度之,得到解答,故记录之. '如图' 只需在 package.json 里面   加上    --max ...

  10. Maven3 快速入门

    Maven3 快速入门 Maven 是目前大型项目构建的必备知识.本章会通过介绍 Maven 的作用,Maven 的基本语法,以及搭建企业级项目架构来快速入门 Maven .前两部分是理论知识只需要了 ...