Swift中的数组要求在创建时其存储的类型是确定的,这点与Oc中的数组有一些不同;
当然,这也不是绝对的,因为有时候数组可以使用范型来约束其类型,只需遵循相应的协议即可,类型并不是完全一致的.
Swift中的数组相比于Oc的数组,功能更加强大;使用更加简便;当然也更加复杂了(光是Array的代码就有9800多行)
1.数组的本质,查看官方的API可以知道数组实际上是一个 结构体.
struct Array<T> : MutableCollectionType,Sliceable { /// The type of element stored by this `Array` typealias Element = T /// Always zero,which is the index of the first element when non-empty. var startIndex: Int { get } /// A "past-the-end" element index; the successor of the last valid /// subscript argument. var endIndex: Int { get } subscript (index: Int) -> T /// Return a *generator* over the elements. /// /// Complexity: O(1) func generate() -> IndexingGenerator<[T]> /// A type that can represent a sub-range of an `Array` typealias SubSlice = Slice<T> subscript (subRange: Range<Int>) -> Slice<T> /// Initialization from an existing buffer does not have "array.init" /// semantics because the caller may retain an alias to buffer. init(_ buffer: _ArrayBuffer<T>) }
2.声明数组的两种方式
(1)使用范型(学过java的应该不会陌生)来约束数组的类型
方式;
var arr :Array<类型>
var arr : Array<Int>
(2) 符号简写方式定义数组变量
方式:
var arr :[类型]
var arr2 :[String]
(3)定义隐式的数组类型,自动推断
方式:
var arr3 = [数组元素1,元素2,.....]
var arr3 = [1,2,3]
上述的arr3不用声明类型,系统可以自动推断为 Int类型
3.数组的创建方式
(1)使用系统提供的init()构造器
使用示例:
arr = Array<Int>()
( 2)使用init(count: 10,repeatedValue:2) 创建一个 个数为 count的,重复值为 repeatedValue的数组
示例,创建一个 元素个数为10,重复值的值为2的数组
arr = Array<Int>(count: 10,repeatedValue: 2)
(3)使用直接赋值法
var arr3 = [1,3]
(1)利用 数组的count属性来遍历,count是数组元素的个数;并且使用数组的下标来访问数组中的元素
var arr3 = [1,3] for var i = 0;i<arr3.count;i++ { arr3[i]+=1 print(arr3[i]) }
(2)使用for in快速遍历
for elem in arr3 { println(elem) }
注意: elem默认是 let常量类型的,不可修改 elem的值
extension Array { /// Construct an empty Array init() /// Construct from an arbitrary sequence with elements of type `T` init<S : SequenceType where T == T>(_ s: S) /// Construct a Array of `count` elements,each initialized to /// `repeatedValue`. init(count: Int,repeatedValue: T) /// How many elements the Array stores var count: Int { get } /// How many elements the `Array` can store without reallocation var capacity: Int { get } /// `true` if and only if the `Array` is empty var isEmpty: Bool { get } /// The first element,or `nil` if the array is empty var first: T? { get } /// The last element,or `nil` if the array is empty var last: T? { get } /// Reserve enough space to store minimumCapacity elements. /// /// PostCondition: `capacity >= minimumCapacity` and the array has /// mutable contiguous storage. /// /// Complexity: O(`count`) mutating func reserveCapacity(minimumCapacity: Int) /// Append newElement to the Array /// /// Complexity: amortized O(1) unless `self`'s storage is shared with another live array; O(`count`) if `self` does not wrap a bridged `NSArray`; otherwise the efficiency is unspecified. mutating func append(newElement: T) /// Append the elements of `newElements` to `self`. /// /// Complexity: O(*length of result*) /// mutating func extend<S : SequenceType where T == T>(newElements: S) /// Remove an element from the end of the Array in O(1). /// Requires: count > 0 mutating func removeLast() -> T /// Insert `newElement` at index `i`. /// /// Requires: `i <= count` /// /// Complexity: O(\ `count`\ ). mutating func insert(newElement: T,atIndex i: Int) /// Remove and return the element at index `i` /// /// Invalidates all indices with respect to `self`. /// /// Complexity: O(\ `count`\ ). mutating func removeAtIndex(index: Int) -> T /// Remove all elements. /// /// Postcondition: `capacity == 0` iff `keepCapacity` is `false`. /// /// Complexity: O(\ `countElements(self)`\ ). mutating func removeAll(keepCapacity: Bool = default) /// Interpose `self` between each consecutive pair of `elements`,/// and concatenate the elements of the resulting sequence. For /// example,`[-1,-2].join([[1,3],[4,5,6],[7,8,9]])` /// yields `[1,3,-1,-2,4,6,7,9]` func join<S : SequenceType where [T] == [T]>(elements: S) -> [T] /// Return the result of repeatedly calling `combine` with an /// accumulated value initialized to `initial` and each element of /// `self`,in turn,i.e. return /// `combine(combine(...combine(combine(initial,self[0]),/// self[1]),...self[count-2]),self[count-1])`. func reduce<U>(initial: U,combine: (U,T) -> U) -> U /// Sort `self` in-place according to `isOrderedBefore`. Requires: /// `isOrderedBefore` induces a `strict weak ordering /// <http://en.wikipedia.org/wiki/Strict_weak_order#Strict_weak_orderings>`__ /// over the elements. mutating func sort(isOrderedBefore: (T,T) -> Bool) /// Return a copy of `self` that has been sorted according to /// `isOrderedBefore`. Requires: `isOrderedBefore` induces a /// `strict weak ordering /// <http://en.wikipedia.org/wiki/Strict_weak_order#Strict_weak_orderings>`__ /// over the elements. func sorted(isOrderedBefore: (T,T) -> Bool) -> [T] /// Return an `Array` containing the results of calling /// `transform(x)` on each element `x` of `self` func map<U>(transform: (T) -> U) -> [U] /// A Array containing the elements of `self` in reverse order func reverse() -> [T] /// Return an `Array` containing the elements `x` of `self` for which /// `includeElement(x)` is `true` func filter(includeElement: (T) -> Bool) -> [T] }
包括构造器,判空,排序,追加,移除等方法;方法使用简单,在此 只举一例:
使用append追加元素
var arr3 = [1,3] arr3.append(4) arr3.append(5) for var i = 0;i<arr3.count;i++ { arr3[i]+=1 print(arr3[i]) }
几点说明:
mutating func这个 前缀,说明了该方法是可变的方法;原因是 数组 和Oc的数组,不一样;Swift中的数组是值类型的;在函数中的形参传入实参时,默认传入的是函数的副本,而无法直接修该该实参;故而出了可变方法,需要在 func之前加上 mutating 关键字.
6.数组的重载运算符+=的妙用
使用数组重载的运算符 += 我们可以直接对可变的数组 (使用 var 修饰) 追加另一个数组(注意,不是单个的元素)进来;从而把两个数组合二为一
var arr3:Array<Int> = [1,3] var arr4 = [6,8] arr3 += arr4 for var i = 0;i<arr3.count;i++ { arr3[i]+=1 print(arr3[i]) }
arr3 数组 合并了 arr4 数组
7.数组的范围下标.我们可以对数组的下标取一个范围来访问数组中的某个范围的元素
对于范围不太理解的详见前面的Swift教程
(1)
方法:
var arr2 = arr1[a...b] var arr2 = arr1[a..<b]
取 arr1数组中下标为 a到 b的 元素,作为一个数组,放入到 arr2数组中;
注意:下标的范围 不要超过 count -1;避免发生 数组越界.
(2)对某个范围下标进行元素批量替换.
我们可以直接使用数组的范围下标来替换对应数组的多个元素,并且不需要关心前后改变的元素个数是否相等.数组 自动改变个数.
var arr3 = [0,1,6] arr3[0...1] = [8,8] println(arr3)
输出:
[8,6]
我们把 arr3数组对应 下标为 0和 1的元素,替换为 4个8;前后元素不一致,但是 数组可以自动改变元素的个数,并且插入到指定的位置.
(3)利用范围下标,快速清空数组
使用:
//清空 数组中的所有元素
arr[0...arr.count-1] = []
详细示例:
var arr3 = [0,8] println("清空数组之前: 数组是 \(arr3)") arr3[0...arr3.count-1] = [] println("清空数组之后,数组是 :\(arr3)")
输出:
清空数组之前: 数组是 [8,6] 清空数组之后,数组是 :[]
可以看到数组中元素个数为0了.
8.多维数组.
定义一个二维数组:
var arr:[[类型]]
或者
var arr:Array<Array<类型>>
var arr :[[Int]] arr = [[1,[5,7]] println(arr[0][1])
var arr2:Array<Array<String>> arr2 = Array<Array<String>>() arr2.insert(["第一个","'第二个"],atIndex: 0) println(arr2)
所谓数组类似,需要类型写法需要嵌套
9.数组的复制与引用类型.
数组复制的规律:
如果数组内的元素是值类型的,如整型,那么数组复制时,会把源数组复制出元素的副本;
如果数组内的元素是引用类型的,如对象,那么 数组复制时,只是复制出元素的指针,修改该指针则也会修改源数组的内容.
复制的形式,很简单,可以直接 使用 等于=,赋值符号 = 即可;
(1)值类型的赋值:
var arr1 = [1,3] var arr2 = arr1 arr2[0] = 3 println(arr2) println(arr1)输出:
[3,3] [1,3]
说明,arr2的修改对 arr1是没有影响的,此数组的复制为值类型的复制;
(2)引用类型的数组复制
首先创建一个有属性 aa的类A,并创建一个构造器
class A { var aa:String init(aa:String) { self.aa = aa } }
var arr1 = [A(aa:"aa1"),A(aa:"aa2")] println(arr1[0].aa) var arr2 = arr1 arr2[0].aa = "aa2来也" println(arr1[0].aa) println(arr2[0].aa)
输出:
aa1 aa2来也 aa2来也
可以看到,当修改 arr2的时候;arr1也被修改了.
Swift更多教程:http://www.jb51.cc/cata/272739