Swift学习笔记之数组(三)

数组

重复值的初始化

除了普通的初始化方法,我们可以通过init(count: Int,repeatedValue:T) 来初始化一个数组填充上重复的值:

var threeDoubles = [Double](count:3,repeatedValue:0.0)

带索引值的遍历

我们可以用for in 遍历数组,如果想要index的话,可以用enumerate(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(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 = []
formoney in oldArray {
    if(money>30){
        filteredArray +=money
    }
}
println(filteredArray)

奇怪的是这里的代码编译不通过:

Playground execution failed: :15:9: error: `Array<Int>` is not identical to `UInt8`
        filteredArray += money

发现原来是+=符号不能用于append,只能用于combine,在外面包个[]即可:

var oldArray = [10,20,45,32]
var filteredArray :Aray = []
formoney in oldArray {
    if(money>30){
        filteredArray += [money]
    }
}
println(filteredArray) //[45,32]

(靠,,居然忘了贴filter的用法,写到后面才发现。。)
filter可以这样实现:

var oldArray = [10,20,45,32]
var filteredArray = oldArray.filter({
        return $0>30
})

println(filteredArray)   //[45,32]

你真的好短啊!

reduce

reduce函数解决了数组中的值整合到某个独立对象的问题。定义如下:

func reduce(initial :U,combine:(U,T)->U)

好吧看起来略抽象。我们还是从for in 开始。比如我们要把数组中的值都加起来放到sum里,那么传统做法是:

var oldArray = [10,20,45,32]
var sum =0 
for money in oldArray {
    sum = sum + money
}
println(sum)   //107    

reduce有两个参数,一个是初始化的值,另一个是一个闭包,闭包邮两个输入的参数,一个是原始值,一个是新进来的值,返回的新值也就是下一轮循环中的旧值,写几个小例子试一下:

var oldArray = [10,20,45,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。


Reference

  • Collection Types
  • ExSwift/Array.swift
  • Higher Order Functions: Map, Filter, Reduce and more – Part 1
  • {(Int)} is not identical to UInt8
  • Swift: Using Map to Deal with Optionals

你可能感兴趣的:(swift学习笔记,书摘,nsarray,swift,nsarray)