题外话
Swift中,在使用Map、FlatMap 、Filter、Reduce 对 Array、Dictionary等集合类型(collection type)进行操作可能对一部分人来说还不是很习惯。但是如果使用熟练的话,可以大大的提高开发的效率及其代码的规范,毕竟人家swift既然推出了这些方法,就是希望我们去应用。
下面一一介绍并测试使用
Map
map 方法返回的是一个数组,其获取一个闭包表达式作为唯一参数,集合中的每个元素调用一次该闭包函数,并返回该元素所映射的值(也可以是不同类型的值)。具体的映射方式和返回值类型由闭包来指定。
let array = [1,2,3,4,5,6]
let newArr = array.map { (num:Int) -> Bool in
return num % 2 == 0 }
print(newArr)
// 打印结果:[false, true, false, true, false, true]
上面的含义:数组array中的每个元素执行闭包里的函数后,并将结果一一返回映射成一个新的数组。上面的写法在swift中还可以沿变成其它的格式,打印结果都是一样的(个人感觉语法好随意,怎么写都对)。
let array = [1,2,3,4,5,6]
let newArray = array.map { num in
return num % 2 == 0 }
print(newArray)
最简洁的写法:其中$0表示数组中的每个元素
let array = [1,2,3,4,5,6]
let newArray = array.map { $0 % 2 == 0 }
print(newArray)
FlatMap
flatMap也可以对一个集合类型的所有元素做一个映射操作。 如上述的例子,如果将map换做
flatMap会输出一样的结果,这里不再演示。那两者的区别是什么?
- flatMap 遍历数组的元素同时,并对这些元素执行闭包中定义的操作。 但唯一不同的是,它会对最终的结果进行了所谓的 “降维” 操作。如下:
let array = [[1,2,3],[4,5,6]]
let newArray = array.map { $0.map{$0+1} }
print(newArray)
let newArray2 = array.flatMap{$0.map{$0+1}}
print(newArray2)
// 打印结果:
newArray : [[2, 3, 4], [5, 6, 7]]
newArray2: [2, 3, 4, 5, 6, 7]
- 官方头文件定义:
public func flatMap(_ transform: (Element) throws -> String?) rethrows -> [String]
从这个定义中可以看,抛出String?,返回String组成的集合。
let optionArray: [Int?] = [1, nil,2, 3,nil];
let optionResult1 = optionArray.map{ $0 }
let optionResult2 = optionArray.flatMap{ $0 }
print(optionResult1)
print(optionResult2)
//打印结果:
optionResult1:[Optional(1), nil, Optional(2), Optional(3), nil]
optionResult2:[1, 2, 3]
神奇,可选类型的数组flatMap映射后,竟然解包了,并且自动过滤掉了为空的元素。经过一番搜索后,看了flatMap内部实现原理才明白,原来当遍历数组中的元素的时候,它的内部会直接解包判断,如若为空直接过滤,如若不为空为将解包后的元素放在一个新的集合,最终返回。有兴趣可参考map & flatMap 浅析
Filter
Filter函数操作会对集合类型进行遍历并将其中的满足条件的元素作为结果数组中的元素进行返回。该函数里面只有一个作为条件判断的语句,闭包会遍历集合里面的元素并将满足条件的结果放在一起:
let array = [1,2,3,4]
let even = array.filter { $0 % 2 == 0 }
//打印结果:[2, 4]
这个平时开发使用的也非常频繁,操作简单。
Reduce
Reduce函数操作会将集合类型里面的所有元素组合成一个新值并返回。reduce中的参数为两个:一个初始值、一个函数闭包。
1.测试一: 初始值字符串为1,并用+将集合中的元素连接最后返回
2.测试二: 初始值为10,并将集合中的元素累加后返回
let chars = ["a","b","c"]
let totalText = chars.reduce("1") {str1,str2 in "\(str1)+\(str2)"}
print(totalText)
let array = [1,2,3,4];
let count = array.reduce(10, { $0+$1 })
print(count)
//打印结果:
totalText :1+a+b+c
count: 20
结束
这些用法理解,并熟练应用才是关键,由于代码测试比较简单,故无完整Demo。