Swift之高阶函数map、flatMap、filter、reduce
Swift相比于 Objective-C又一个重要的优点,它对函数式编程提供了很好的支持, Swift提供了 map、filter、reduce这三个高阶函数作为对容器的支持。
map
解释:可以对数组中的每一个元素做一次处理
var arrayList: [Int] = [90, 19, 9, 78, 10, 32, 45]
let mapList = arrayList.map { (number) -> String in
return "\(number)"
}//将数字Int转化为字符串
print(mapList)//得到的是新函数
//结果:mapList:["90", "19", "9", "78", "10", "32", "45"]
官方文档解释:
/// Returns an array containing the results of mapping the given closure
/// over the sequence's elements.
///
/// In this example, `map` is used first to convert the names in the array
/// to lowercase strings and then to count their characters.
///
/// let cast = ["Vivien", "Marlon", "Kim", "Karl"]
/// let lowercaseNames = cast.map { $0.lowercased() }
/// // 'lowercaseNames' == ["vivien", "marlon", "kim", "karl"]
/// let letterCounts = cast.map { $0.count }
/// // 'letterCounts' == [6, 6, 3, 4]
///
/// - Parameter transform: A mapping closure. `transform` accepts an
/// element of this sequence as its parameter and returns a transformed
/// value of the same or of a different type.
/// - Returns: An array containing the transformed elements of this//返回一个数组array
/// sequence.
@inlinable public func map<T>(_ transform: (Element) throws -> T) rethrows -> [T]
//T 是泛型,返回你需要的类型,可以知道官方demo中简写方式
let letterCounts = cast.map { $0.count }//各个长度
flatMap与map不同之处
注意:序列可选类型,Swift 4.1之前可以使用flatMap,现在需要compactMap:
一般情况下map与flatMap的功能是相似的,都可以执行map工作。
compactMap的改变是在于将flatMap处理non-optional序列类型,compact处理optional类型
- flatMap返回后的数组中不存在nil,同时它会把Optional解包
let strList:[String?] = ["Apple", "Orange", "Puple", "", nil]
let lengthListOp = strList.map { (item) -> Int? in
return item?.count
}
lengthListOp // [Optional(5), Optional(6), Optional(5), Optional(0), nil]
let lengthList = strList.compactMap { (item) -> Int? in
guard item.count > 0 else {
return nil
}
return item.count
}
lengthList // [5, 6, 5, 0]
- compactMap还能把数组中存有数组的数组(二维数组、N维数组)一同打开变成一个新的数组
let newList = [["2", "32", "Apple"], ["02", "132", "Orange"], ["20", "320", "Puple"]]
let mapNew = newList.map { (list) -> [String] in
return list.map({ (item) -> String in
return item
})
}
//简写代码:仅仅只是查看的话
let simpleNew = newList.map { $0}
print(mapNew)
print(simpleNew)
//结果:[["2", "32", "Apple"], ["02", "132", "Orange"], ["20", "320", "Puple"]]
let flatNew = newList.flatMap { $0}
print(flatNew)
//结果:["2", "32", "Apple", "02", "132", "Orange", "20", "320", "Puple"]
- flatMap也能把两个不同的数组合并成一个数组,这个合并的数组元素个数是前面两个数组元素个数的乘积
let fruits = ["Apple", "Orange", "Puple"]
let counts = [2, 3]
let array = counts.flatMap { count in
fruits.map ({ fruit in
return fruit + " \(count)"
})
}
print(array)
//结果:["Apple 2", "Orange 2", "Puple 2", "Apple 3", "Orange 3", "Puple 3"]
filer
说明:过滤,可以对数组中的元素按照某种规则进行一次过滤
let fruits = ["Apple", "Orange", "Puple"]
let filterList = fruits.filter { (item) -> Bool in
return item.contains("p")//包含p
}
print(filterList)
//结果:["Apple", "Puple"]
reduce
说明:方法把数组元素组合计算为一个值,并且会接受一个初始值,这个初始值得类型可能和数组元素类型不同。
//字符串拼接
let fruits = ["Apple", "Orange", "Puple"]
let fruitReduce = fruits.reduce("100") { (result, item) -> String in
return result + "、" + item
}
print(fruitReduce)
//结果:100、Apple、Orange、Puple
//方式二:
func appendString(string1: String, string2: String) -> String {
return string1 + "、" + string2
}
let newFruitReduce = fruits.reduce("10", appendString)
//结果:10、Apple、Orange、Puple
有关Swift.map高阶函数的应用
这些函数不仅仅使用与数组Array类型,一般凡是有序的数据例如:String子元素是Chart、Dictionary对应子元素一个键值对等等这些都是可以用这些高阶函数,这些宝藏还需自己开发中挖掘
Demo如下:
let newStr = "Hello World".filter { (chart) -> Bool in
return !chart.description.elementsEqual("o")
}
print(newStr)// 剔除掉字符串中的o
var dic: [String : Any] = ["name": "XiaoMing", "age": 12, "sex": "Man"]
let newDic = dic.mapValues { (item) -> String in
return "\(item)"
}
print(newDic)
//结果如下:
Hell Wrld
["sex": "Man", "name": "XiaoMing", "age": "12"]