数组
重复值的初始化
除了普通的初始化方法,我们可以通过init(count: Int,repeatedValue:T)
来初始化一个数组填充上重复的值:
- var threeDoubles = [Double](count:3,repeatedValue:0.0)
带索引值的遍历
我们可以用for in
遍历数组,如果想要index
的话,可以用enumerate<Seq : SequenceType>(base:Seq)
:
- let arr = ["a","b"]
- for(index,value) in enumerate(arr) {
- println("\(index):\(value)")
- } //0:a 1:b
赋值与拷贝
Swift中数组和字典均是结构体的形式实现的,和NSArray
那一套不太一样,所以赋值的时候其实是给了一份拷贝:
- let hd = Resolution(width:1920,height:1000)
- var cinema = hd
- cinema.height =233
- cinema //1920 233
- hd //1920 1000
高阶函数
Swift有一些Higher Order Function :map,filter和reduce。使用得当的话可以省去很多不必要的代码。
map
‘map’可以把一个数组按照一定的规则转换成另一个数组,定义如下:
- func map<U>(transform:(T) -> U)-> U[]
也就是说它接受一个函数叫做transform
,然后这个函数可以把T类型转换成U类型的并返回(也就是(T) ->U
),最终map
返回的是U类型的集合。下面的表达式更有助于理解:
- [x1,x2,...,xn].map(f) ->[f(x1),f(x2),f(xn)]
如果用for in
来实现,则需要这样:
- var newArray : Array(T) = []
- for item in oldArray {
- newArray +=f(item)
- }
举个例子,我们可以这样把价格数组中的数字前面都加上¥符号:
- var oldArray = [10,20,45,32]
- var newArray = oldarray.map({money in "¥\(money)"})
- println(newArray) //[¥10,¥20,¥45,¥32]
如果你觉得money in
也有点多余的话可以用$0
:
- newArray = oldArray.map({"\($0)¥"})
filter
方法如其名, filter
起到的就是筛选的功能,参数事一个用来判断是否筛除的筛选闭包,定义如下:
- func filter(includeElement(T)->(T))
还是举个例子说明一下,首先看下传统的for in
实现的方法:
- var oldArray = [10,20,45,32]
- var filteredArray :Aray<Int> = []
- formoney in oldArray {
- if(money>30){
- filteredArray +=money
- }
- }
- println(filteredArray)
奇怪的是这里的代码编译不通过:
- Playground execution Failed: <EXPR>:15:9: error: `Array<Int>` is not identical to `UInt8`
- filteredArray += money
发现原来是+=
符号不能用于append
,只能用于combine
,在外面包个[]
即可:
- var oldArray = [10,32]
- var filteredArray :Aray<Int> = []
- formoney in oldArray {
- if(money>30){
- filteredArray += [money]
- }
- }
- println(filteredArray) //[45,32]
(靠,,居然忘了贴filter
的用法,写到后面才发现。。)
用filter
可以这样实现:
- var oldArray = [10,32]
- var filteredArray = oldArray.filter({
- return $0>30
- })
-
- println(filteredArray) //[45,32]
你真的好短啊!
reduce
reduce
函数解决了数组中的值整合到某个独立对象的问题。定义如下:
- func reduce<U>(initial :U,combine:(U,T)->U)
好吧看起来略抽象。我们还是从for in
开始。比如我们要把数组中的值都加起来放到sum
里,那么传统做法是:
- var oldArray = [10,32]
- var sum =0
- for money in oldArray {
- sum = sum + money
- }
- println(sum) //107
reduce
有两个参数,一个是初始化的值,另一个是一个闭包,闭包邮两个输入的参数,一个是原始值,一个是新进来的值,返回的新值也就是下一轮循环中的旧值,写几个小例子试一下:
- var oldArray = [10,32]
- var sum =0
- sum = oldArray.reduce(0,{$0 + $1})//0+10+20+45+32 =107
- sum = oldArray.reduce(1,{$0 + $1})//1+10+20+45+32 =108
- sum = oldArray.reduce(5,{$0 * $1})//5*10*20*45*32
- sum = oldArray.reduce(0,+) //0+10+20+45+32 = 107
- println(sum) //107
大概就是这些!
map 用来解包可选类型
我们在解包可选类型的时候,通常会这么做:
- func increment(someNumber:Int?) -> Int? {
- if let number = someNumber {
- return number + 1
- }else {
- return nil
- }
- }
- increment(5) //Some 6
- increment(nil) //nil
我们也可以用map来实现:
- func increment(someNumber: Int?) -> Int? {
- return someNumber.map { number in number + 1 }
- }
-
- increment(5) // Some 6
- increment(nil) // nil
包括其他可选类型也是可行的,比如 String :
- func hello(someName: String?) -> String? {
- return someName.map { name in "Hello,\(name)"}
- }
-
- hello("NatashaTheRobot") // Some "Hello,NatashaTheRobot"
- hello(nil) // nil
再搭配上 ??
符号,嗯基本够了:
- func hello(someName: String?) -> String {
- return someName.map { name in "Hello,\ (name)" } ?? "Hello world!"
- }
-
- hello("NatashaTheRobot") // "Hello,NatashaTheRobot"
- hello(nil) // "Hello world!"
扩展
数组和字典十分常用,而官方的方法功能有限。我们可以学习ExSwift 中 Array.swift 的内容,给 Array 添加一些 Extension。