高阶函数及参数的省略

常见定义函数

1
2
3
4
5
6
let normalFunc = {
() -> Int in
return 10086
}
let normalResult = normalFunc()
// normalResult = 10086

###函数参数的『省略』

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 以数组排序函数为例:
var numberArr = [1,7,4,6,3,2,5]
let res1 = numberArr.sort()
let res2 = numberArr.sort {
(num1: Int, num2: Int) -> Bool in
return num1>num2
}
let res3 = numberArr.sort {
(num1: Int, num2: Int) in
return num1>num2
}
let res4 = numberArr.sort {
(num1, num2) in
return num1>num2
}
let res5 = numberArr.sort {
return $0 > $1
}
let res6 = numberArr.sort {
$0 > $1
}
let res7 = numberArr.sort(>)

变化过程
{ (num1: Int, num2: Int) -> Bool in return num1>num2 }
{ (num1: Int, num2: Int) in return num1>num2 }
{ (num1, num2) in return num1>num2 }
{ return $0 > $1 }
{ $0 > $1 }

函数式编程

案例一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
func square(a:Float) -> Float {
return a * a
}
func cube(a:Float) -> Float {
return a * a * a
}
func averageSumOfSquares(a:Float,b:Float) -> Float {
return (square(a) + square(b)) / 2.0
}
func averageSumOfCubes(a:Float,b:Float) -> Float {
return (cube(a) + cube(b)) / 2.0
}
// 像Swift的Currying(柯里化),可以灵活调配使用
func averageOfFunction(a a:Float,b:Float,f:(Float -> Float)) -> Float {
return (f(a) + f(b)) / 2
}
let squareResult1 = averageOfFunction(a: 2, b: 4, f: square)
let squareResult2 = averageOfFunction(a: 2, b: 4, f: {
(a: Float) -> Float in
return a * a
})
//{(x: Float) -> Float in return x * x}
//{x in return x * x}
//{x in x * x}
//{$0 * $0}
let squareResult3 = averageOfFunction(a: 2, b: 4, f: {$0 * $0})

案例二

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 正统高阶函数样式
func sum1(value: Int) -> (Int -> Int) {
func adder(otherValue: Int) -> Int {
return otherValue + value
}
return adder
}
// 省略后
func sum2(value: Int) -> (Int -> Int) {
return { $0 + value }
}
let result1 = sum1(2)(3)
let result2 = sum2(5)(3)
// 改造函数完毕
func funcMathMethod1(first: Int -> Int, _/*起到变量匿名作用*/ second: Int -> Int) -> Int -> Int {
return { second(first($0)) }
}
let f1 = funcMathMethod1({$0 + 2}, {$0 / 3})
f1(7)
let f2 = funcMathMethod1({$0 * $0}, {$0 / 4})
f2(10)
// Tip: 使用函数式编程,要是用得不好容易造成可读性很差,那优化如下
typealias MathFunc = Int -> Int
func funcMathMethod2(f: MathFunc, _ s: MathFunc) -> MathFunc {
return { s(f($0)) }
}
let readability = funcMathMethod1({$0 + 2}, {$0 / 3})
readability(7)

swift原生常用的高阶函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// map
var numberArr = [1,7,4,6,3,2,5]
let mapArray = numberArr.map { (num: Int) -> String in
return "第\(num)名"
}
let mapArray2 = numberArr.map({"第\($0)名"})
mapArray2
// 可选型随意解包 str 可以为 nil
let str: String? = "1234567890"
let mapStr = str.map({"第\($0)名"})
mapStr
// filter
let filArr = numberArr.filter { (num: Int) -> Bool in
return num > 4
}
let filArr2 = numberArr.filter({ $0 > 4 })
filArr2
// reduce
let sum = numberArr.reduce(0) { (presum:Int, num:Int) -> Int in
return presum + num
}
let sum2 = numberArr.reduce(10, combine: {$0 + $1})
sum2
let sumToStr = numberArr.reduce("") { (str: String, num: Int) -> String in
str + String(num)
}
// 求一个数组中偶数的平方和(一口气使用swift提供的三个高阶函数)
//[1,2,3,4,5,6,7] -> [2,4,6] -> 4+16+36 = 56
let result = numberArr.filter({$0%2==0}).map({$0*$0}).reduce(0, combine: {$0+$1})
result // result = 56

面试题1

1
2
3
4
5
6
7
8
9
10
11
12
13
// 面试题:用数组的 reduce 方法实现 map 的功能。
let arr = [1, 3, 2]
// map简易实现
let res = arr.map({$0*2})
// Array.reduce(<#T##initial: T##T#>, combine: <#T##(T, Int) throws -> T#>)
// 输出数据类型与初始化占位数据类型(initial)一致
let res2 = arr.reduce([]) {
(a: [Int], element: Int) -> [Int] in
var t = Array(a)
t.append(element * 2)
return t
}

面试题1

1
2
3
4
5
6
7
8
9
10
11
12
13
// 面试题:用 reduce 方法一次求出数组中奇数的和、以及偶数乘积
// 使用元组,注意占位数据(0, 1),第一联合数据a :(Int, Int),函数输出数据(Int, Int) 三者类型一致
let arr2 = [1, 3, 2, 4]
let res3: (Int, Int) = arr2.reduce((0, 1)) {
(a :(Int, Int), element: Int) -> (Int, Int) in
if element % 2 == 0 {
return (a.0, a.1 * element)
} else {
return (a.0 + element, a.1)
}
}