swift中比较常用的高阶函数有:map、flatMap、filter、reduce
更多swift相关教程可以参考极客学院文章
map可以对数组中的每一个元素做一次处理
// 计算字符串的长度
let stringArray = ["Objective-C", "Swift", "HTML", "CSS", "JavaScript"]
func stringCount(string: String) -> Int {
return string.characters.count
}
stringArray.map(stringCount)
stringArray.map({string -> Int in
return string.characters.count
})
// $0代表数组中的每一个元素
stringArray.map{
return $0.characters.count
}
public enum Optional<Wrapped> : _Reflectable, NilLiteralConvertible {
/// If `self == nil`, returns `nil`. Otherwise, returns `f(self!)`.
@warn_unused_result
public func map<U>(@noescape f: (Wrapped) throws -> U) rethrows -> U?
}
extension CollectionType {
/// Returns an `Array` containing the results of mapping `transform`
/// over `self`.
///
/// - Complexity: O(N).
@warn_unused_result
public func map<T>(@noescape transform: (Self.Generator.Element) throws -> T) rethrows -> [T]
}
源码中的一些关键字在这里介绍一下:
@warn_unused_result:表示如果没有检查或者使用该方法的返回值,编译器就会报警告。
@noescape:表示transform这个闭包是非逃逸闭包,它只能在当前函数map中执行,不能脱离当前函数执行。这使得编译器可以明确的知道运行时的上下文环境(因此,在非逃逸闭包中可以不用写self),进而进行一些优化
///原来类型: Int?,返回值类型:String?
var value:Int? = 1
var result = value.map { String("result = \($0)") }
/// "Optional("result = 1")"
print(result)
var value:Int? = nil
var result = value.map { String("result = \($0)") }
/// "nil"
print(result)
我们可以使用map方法遍历数组中的所有元素,并对这些元素一一进行一样的操作(函数方法)。map方法返回完成操作后的数组。
1. 传统写法:
var values = [1,3,5,7]
var results = [Int]()
for var value in values {
value *= 2
results.append(value)
}
//"[2, 6, 10, 14]"
print(results)
//传统的For-in实现起来代码很多,不简介,而且效率没有高阶函数高。
2. 使用map高阶函数
let results = values.map ({ (element) -> Int in
return element * 2
})
//"[2, 6, 10, 14]"
此外还有更加精简的写法:
let results = values.map { $0 * 2 }
//"[2, 6, 10, 14]"
3.
通过上面的代码对比,我们可以看出高阶函数精简写法是多么的优雅,就像写诗一样。下面我们来探究一下怎么就精简这么短小了呢,连return语句都不需要了
let results = values.map ({ (element) -> Int in return element * 2 })
//"[2, 6, 10, 14]"
let results = values.map ({ element in return element * 2 })
//"[2, 6, 10, 14]"
let results = values.map ({ element in element * 2 })
//"[2, 6, 10, 14]"
let results = values.map ({ $0 * 2 })//$0即代表闭包中的第一个参数。
//"[2, 6, 10, 14]"
let results = values.map (){ $0 * 2 }
//"[2, 6, 10, 14]"
如果函数只需要闭包表达式一个参数,当您使用尾随闭包时,您甚至可以把()省略掉:
let results = values.map { $0 * 2 }
//"[2, 6, 10, 14]"
let array = ["Apple", "Orange", "Puple", ""]
let arr1 = array.map { a -> Int? in
let length = a.characters.count
guard length > 0 else { return nil }
return length
}
arr1 // [{some 5}, {some 6}, {some 5}, nil]
let arr2 = array.flatMap { a-> Int? in
let length = a.characters.count
guard length > 0 else { return nil}
return length
}
arr2 // [5, 6, 5]
let array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let arr1 = array.map{ $0 }
arr1 // [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let arr2 = array.flatMap{ $0 }
arr2 // [1, 2, 3, 4, 5, 6, 7, 8, 9]
let fruits = ["Apple", "Orange", "Puple"]
let counts = [2, 3, 5]
let array = counts.flatMap { count in
fruits.map ({ fruit in
return fruit + " \(count)"
})
}
array // ["Apple 2", "Orange 2", "Puple 2", "Apple 3", "Orange 3", "Puple 3", "Apple 5", "Orange 5", "Puple 5"]
filer:过滤,可以对数组中的元素按照某种规则进行一次过滤
// 筛选出字符串的长度小于10的字符串
let stringArray = ["Objective-C", "Swift", "HTML", "CSS", "JavaScript"]
func stringCountLess10(string: String) -> Bool {
return string.characters.count < 10
}
stringArray.filter(stringCountLess10)
stringArray.filter({string -> Bool in
return string.characters.count < 10
})
// $0表示数组中的每一个元素
stringArray.filter{
return $0.characters.count < 10
}
reduce:计算,可以对数组的元素进行计算
// 将数组中的每个字符串用‘、’拼接
let stringArray = ["Objective-C", "Swift", "HTML", "CSS", "JavaScript"]
func appendString(string1: String, string2: String) -> String {
return string1 == "" ? string2 : string1 + "、" + string2
}
// reduce方法中的第一个参数是初始值
stringArray.reduce("", appendString)
stringArray.reduce("", {(string1, string2) -> String in
return string1 == "" ? string2 : string1 + "、" + string2
})
// $0表示计算后的结果, $1表示数组中的每一个元素
stringArray.reduce("", {
return $0 == "" ? $1 : $0 + "、" + $1
})
参考博客,教程:
http://wiki.jikexueyuan.com/project/swift/chapter2/07_Closures.html