Swift心得笔记之集合类型
数组
重复值的初始化
除了普通的初始化方法,我们可以通过init(count:Int,repeatedValue:T)来初始化一个数组并填充上重复的值:
//[0.0,0.0,0.0] varthreeDoubles=[Double](count:3,repeatedValue:0.0)
带索引值的遍历
我们可以用forin遍历数组,如果想要index的话,可以用enumerate<Seq:SequenceType>(base:Seq):
letarr=["a","b"] for(index,value)inenumerate(arr){ println("\(index):\(value)") } //0:a //1:b
赋值与拷贝
Swift中数组和字典均是结构体的形式实现的,和NSArray那一套不太一样,所以赋值的时候其实是给了一份拷贝:
lethd=Resolution(width:1920,height:1080) varcinema=hd cinema.height=233 cinema //1920233 hd //19201080
高阶函数
Swift有一些HigherOrderFunctions:map、filter和reduce。使用得当的话可以省去很多不必要的代码。
map
map可以把一个数组按照一定的规则转换成另一个数组,定义如下:
funcmap<U>(transform:(T)->U)->U[]
也就是说它接受一个函数叫做transform,然后这个函数可以把T类型的转换成U类型的并返回(也就是(T)->U),最终map返回的是U类型的集合。
下面的表达式更有助于理解:
[x1,x2,...,xn].map(f)->[f(x1),f(x2),...,f(xn)]
如果用forin来实现,则需要这样:
varnewArray:Array<T>=[] foriteminoldArray{ newArray+=f(item) }
举个例子,我们可以这样把价格数组中的数字前面都加上¥符号:
varoldArray=[10,20,45,32] varnewArray=oldArray.map({moneyin"¥\(money)"}) println(newArray)//[¥10,¥20,¥45,¥32]
如果你觉得moneyin也有点多余的话可以用$0:
newArray=oldArray.map({"\($0)"})
filter
方法如其名,filter起到的就是筛选的功能,参数是一个用来判断是否筛除的筛选闭包,定义如下:
funcfilter(includeElement:(T)->Bool)->[T]
还是举个例子说明一下。首先先看下传统的forin实现的方法:
varoldArray=[10,20,45,32] varfilteredArray:Array<Int>=[] formoneyinoldArray{ if(money>30){ filteredArray+=money } } println(filteredArray)
奇怪的是这里的代码编译不通过:
Playgroundexecutionfailed:<EXPR>:15:9:error:'Array<Int>'isnotidenticalto'UInt8' filteredArray+=money
发现原来是+=符号不能用于append,只能用于combine,在外面包个[]即可:
varoldArray=[10,20,45,32] varfilteredArray:Array<Int>=[] formoneyinoldArray{ if(money>30){ filteredArray+=[money] } } println(filteredArray)//[45,32]
(靠。。居然忘了贴filter的用法,写到后面才发现。。)
用filter可以这样实现:
varoldArray=[10,20,45,32] varfilteredArray =oldArray.filter({ return$0>30 }) println(filteredArray)//[45,32]
你真的好短啊!
reduce
reduce函数解决了把数组中的值整合到某个独立对象的问题。定义如下:
funcreduce<U>(initial:U,combine:(U,T)->U)->U
好吧看起来略抽象。我们还是从forin开始。比如我们要把数组中的值都加起来放到sum里,那么传统做法是:
varoldArray=[10,20,45,32] varsum=0 formoneyinoldArray{ sum=sum+money } println(sum)//107
reduce有两个参数,一个是初始化的值,另一个是一个闭包,闭包有两个输入的参数,一个是原始值,一个是新进来的值,返回的新值也就是下一轮循环中的旧值。写几个小例子试一下:
varoldArray=[10,20,45,32] varsum=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=1440000 sum=oldArray.reduce(0,+)//0+10+20+45+32=107 println(sum)
大概就是这些。
map用来解包可选类型
我们在解包可选类型的时候,通常会这么做:
funcincrement(someNumber:Int?)->Int?{ ifletnumber=someNumber{ returnnumber+1 }else{ returnnil } } increment(5) //Some6 increment(nil)//nil
我们也可以用map来实现:
funcincrement(someNumber:Int?)->Int?{ returnsomeNumber.map{numberinnumber+1} }
increment(5) //Some6 increment(nil)//nil