8.1 数组集合

数组是一串有序的由相同类型元素构成的集合。数组中的集合元素是有序的,可以重复出现。图8-1是一个班级集合数组,在这个集合中有一些学生,这些学生是有序的,顺序是它们放到集合中的顺序,我们可以通过下标序号访问它们。这就像老师给进入班级的人分配学号,第一个报到的是“张三”,老师给他分配的是0,第二个报到的是“李四”,老师给他分配的是1,以此类推,最后一个序号应该是“学生人数-1”。

{%}

图 8-1 数组集合

提示 数组更关心元素是否有序,而对于是否重复则不关心。请大家记住这个原则。

8.1.1 数组声明与初始化

Swift为数组提供Array结构体类型,在声明一个数组的时候可以使用下面的语句之一。

  1. var studentList1: Array<String>
  2. var studentList2: [String]

其中变量studentList1明确指定类型为Array是泛型,说明在这个数组中只能存放字符串类型的数据。studentList2变量也是声明一个只能存放字符串类型的数组。[String]Array是等价的,[String]是简化写法。

上面声明的集合事实上还不能用,还需要进行初始化,集合类型往往在声明的同时进行初始化。示例代码如下:

  1. var studentList1: Array<String> = ["张三","李四","王五","董六"]
  2. var studentList2: [String] = ["张三","李四","王五","董六"]
  3. let studentList3: [String] = ["张三","李四","王五","董六"]
  4. var studentList4 = [String]()

上述代码都是对数组进行声明和初始化,①~③采用["张三","李四","王五","董六"]的方式进行初始化,这是数组的表示方式,它的语法如图8-2所示。

{%}

图 8-2 数组表示语法

这个语法类似于JSON1中的数组,数组以“[”(左中括号)开始,“]”(右中括号)结束,值之间使用“,”(逗号)进行分隔。

1JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它基于JavaScript(Standard ECMA-262 3rd Edition-December 1999)的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、 C++、C#、Java、JavaScript、Perl、Python等)。这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成。——百度百科 http://baike.baidu.com/view/136475.htm

第③行是let声明数组,let声明的数组是不可变数组,必须在声明的同时进行初始化,一旦被初始化,就不可以被修改。不可变数组在访问效率上比可变数组(var声明的数组)要高,可变数组通过牺牲访问效率换取可变。例如,当往可变数组内添加新元素的时候,数组要重新改变它的大小,然后重排它们的索引下标,这些都会影响性能。因此如果你真的确定数组是不需要修改的,那么你应该将它声明为let

代码第④行是初始化一个空的数组,它与var studentList2: [String]是有区别的。var studentList2: [String]语句声明没有初始化,即没有开辟内存空间,而第④行的String进行了初始化,只不过没有任何元素。

8.1.2 数组的修改

我们可以对数组中的元素进行追加、插入、删除和替换等修改操作。追加元素可以使用数组append方法或+操作符实现,插入元素可以使用数组的insert方法实现,删除元素可以使用数组的removeAtIndex方法实现。

下面我们来看一个示例:

  1. var studentList: [String] = ["张三","李四","王五"]
  2. println(studentList)
  3. studentList.append("董六")
  4. println(studentList)
  5. studentList += ["刘备", "关羽"]
  6. println(studentList)
  7. studentList.insert("张飞",atIndex:studentList.count)
  8. println(studentList)
  9. let removeStudent = studentList.removeAtIndex(0)
  10. println(studentList)
  11. studentList[0] = "诸葛亮"
  12. println(studentList)

输出结果如下:

  1. [张三, 李四, 王五]
  2. [张三, 李四, 王五, 董六]
  3. [张三, 李四, 王五, 董六, 刘备, 关羽]
  4. [张三, 李四, 王五, 董六, 刘备, 关羽, 张飞]
  5. [李四, 王五, 董六, 刘备, 关羽, 张飞]
  6. [诸葛亮, 王五, 董六, 刘备, 关羽, 张飞]

上述代码第①行是声明并初始化数组studentList,第②行是打印数组,第③行追加了一个元素“董六”。如果要想追加多个元素,可以采用第⑤行+=操作符,它能够追加多个元素。

第⑦行是使用insert方法插入元素,atIndex参数是插入的位置。本例中传递的是studentList.countcount是数组的属性,可以获得数组的长度。

第⑨行代码是使用removeAtIndex方法删除元素,参数是删除的位置,方法返回值是删除的元素。本例中传递的是0,表示删除第一个元素。removeAtIndex方法成功执行后,第一个元素会被删除,因此最后studentList输出的结果中没有“张三”,而这个时候removeStudent常量内容是“张三”。

第⑪行代码是替换第一个元素。

8.1.3 数组遍历

数组最常用的操作是遍历集合,就是将数组中的每一个元素取出来,进行操作或计算。整个遍历过程与循环分不开,我们可以使用for in循环进行遍历。

下面是遍历数组的示例代码:

  1. var studentList: [String] = ["张三","李四","王五"]
  2. for item in studentList {
  3. println (item)
  4. }
  5. for (index, value) in enumerate(studentList) {
  6. println("Item \(index + 1 ) : \(value)")
  7. }

运行结果如下:

  1. 张三
  2. 李四
  3. 王五
  4. Item 1 : 张三
  5. Item 2 : 李四
  6. Item 3 : 王五

从上述代码可见,遍历数组有两种方法,它们都采用for in语句。第①行代码的遍历适合于不需要循环变量的情况,for in可以直接从数组studentList中逐一取出元素,然后进行打印输出。第②行代码的遍历适合于需要循环变量的情况,enumerate函数可以取出数组的索引和元素,其中(index, value)是元组类型。