一、filter方法:可以过滤数组中不满足筛选条件的元素,返回满足筛选条件的元素所组成的数组。
func filter(_ isIncluded: (UInt8) throws -> Bool) rethrows -> [UInt8]
filter方法参数是一个闭包,闭包返回值是Bool类型,当满足筛选条件的时闭包才有返回值,filter返回值是一个
用法如下:
let array = [1,2,3,4]
let filteredArray = array.filter{$0 > 2}
for i in filteredArray {//实际相当于for i in [3,4], 最后输出 3 和 4
print(i)
}
二、map方法
map方法将原来数组中元素映射到一个新的数组中:
func map(_ transform: (T) throws -> T) rethrows -> [T]
map方法参数是一个闭包,闭包中可以执行相应的逻辑,执行完毕后返回一个
let array = [1,2,3,4]
let mappedArray = array.map{$0 * 10}
for i in mappedArray {
print(i)//会输出10、20、30、40
}
在工程中,我们常常会定义自己的类,有时候需要单独获取这些类的某个属性。习惯做法是用循环语句取出数组中的所有类的实例,然后把这些属性存到一个数组中,有了map函数后代码会变得非常简单。
例如,我们自定义了一个学生类,它有两个属性:名字和年龄,通过狗在其给这两个属性赋值:
struct student {
var name: String
var age: Int
}
现在新建一个student的类型的数组,里面放了四个学生的实例:
let studentArr:[Student] = [Student(name: "张三", age: 13),
Student(name: "李四", age: 14),
Student(name: "王五", age: 15),
Student(name: "赵六", age: 16)]
现在我们来获取所有学生的名字,使用传统的方法:
var nameArr: [String] = []
for student in studentArr {
nameArr.append(student.name)
}
for name in nameArr {
print(name)//输出张三、李四、王五、赵六
}
使用map函数:
let nameArr = studentArr.map{$0.name}
for name in nameArr {
print(name)//输出张三、李四、王五、赵六
}
可以看出map方法即高效,又容易理解
三、flatMap方法
flatMap可用于可选型与数组,可选型中的faltMap会把嵌套的可选型封装成一个可选型,而数组中的flatMap会检测数组中有没有嵌套的数组,把嵌套的数组解构再重组成一个数组。
func flatMap(_ transform: (T) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Element] where SegmentOfResult : Sequence
比如你通过不同额解构得到了两组数组,一组是尺寸,一组是颜色,如果需要混合两种数据,可能会这样做:
let sizes = ["S","M","L"]
let colors = ["red","black","white"]
let groups = sizes.map { size in
colors.map({ color in
return (size + " " + color)
})
}
print(groups)
控制台输出: [["S red", "S black", "S white"], ["M red", "M black", "M white"], ["L red", "L black", "L white"]],我们需要的是一个所有组合的一维数组,但是得到的是一个嵌套的二维数组,
当然也是可以实现的,我们用for循环来实现
let sizes = ["S","M","L"]
let colors = ["red","black","white"]
var groups: [String] = []
for size in sizes {
for color in colors {
groups.append(size+color)
}
}
print(groups)
控制台输出:["Sred", "Sblack", "Swhite", "Mred", "Mblack", "Mwhite", "Lred", "Lblack", "Lwhite"],这样实现起来会比较麻烦,不得不同样遍历两次,代码很难读,并且且套本来并没有发挥任何作用,如果你只需要底层数据,那么在最外层使用flatMap代替map:
let groups = sizes.flatMap { size in
colors.map({ color in
return (size + " " + color)
})
}
控制台输出:["S red", "S black", "S white", "M red", "M black", "M white", "L red", "L black", "L white"],现在嵌套已经被解除了
四、reduce方法
reduces方法可以把数组编程一个元素。首先需要指定一个初始值,然后在闭包中写一个reduce规则,接着reduce方法就会开始递归地对数组中的元素进行闭包中的运算,直到运算出最后一个结果,实例如下:
func reduce(_ initialResult: Result, _ nextPartialResult: (Result, Element) throws -> Result) rethrows -> Result
接收两个参数,一个为类型Result的初始值,另一个为把类型为Result的元素和类型为Element的元素组合成一个类型为Result的值的函数。
最终结果整个数组就变成了一个类型为Result的值。
let array = [1,2,3,4]
let result = array.reduce(0, {$0 + $1})
//简化写法
let result = array.reduce(0, +)
print(result)//输出10
需要注意的是combine函数的两参数类型不同,$0为计算结果类型,$1为数组元素类型。
下面是reduce的三种用法。其实都一样,只是第二种更简洁,但是比较难懂,这两个方法都是返回数组中有多少个不相同的数。
extension Array where Element: Comparable {
func countUniques() -> Int {
let sorted = self.sorted(by: <)
let initial: (Element?, Int) = (.none, 0)
let reduced = sorted.reduce(initial) { (result, item) -> (Element?, Int) in
if result.0 == item {
return (item, result.1)
}else {
return (item, result.1+1)
}
}
return reduced.1
}
//第二种
func countTheUnique() -> Int {
let sorted = self.sorted(by: <)
let initial: (Element?, Int) = (.none, 0)
let result = sorted.reduce(initial, {($1, $0.0 == $1 ? $0.1 : $0.1+1)})
return result.1
}
//第三种可以一行代码完成
func countUnique() -> Int {
return self.sorted(by: <).reduce((.none, 0), {($1, $0.0 == $1 ? $0.1 : $0.1+1)}).1
}
}
print([10,2,3,4,5,5,5,1].countTheUnique()) // 6
print([10,2,3,4,5,5,5,1].countUnique()) // 6
print([10,2,3,4,5,5,5,1].countUniques()) // 6
五、sorted方法
sorted方法接受另一个函数作为参数,这个参数是一个决定两个元素谁放在前面的函数型参数,默认是使用小于号的比较。通常会把排序函数写成一个闭包,闭包会被不停的调用,在内部采用了快速排序或者其它任意的排序方法。
func sorted(by areInIncreasingOrder: (Int, Int) throws -> Bool) rethrows -> [Int]
let array = [3,1,2,4]
let sortedArr = array.sorted{$0 < $1}
//简写,默认从小到大
let sortedArr = array.sorted()
print(sortedArr)//输出 [1, 2, 3, 4]
六、forEach
let array = [1,2,3,4]
array.forEach {
if $0 == 3 {
return
}
print($0)//输出1,2,4
}
注意:forEach闭包中的return语句只会从当前的闭包中返回,并不会中断整个遍历
七、contains方法
如果给定的数组中存在特定的元素,则contains方法就会返回true,否则返回false。
let array = [1,2,3,4]
print(array.contains(1))//输出true
八、index()方法
let array = [1,2,3,4]
//当前值的下标
print(array.index(of: 2)!)//输出1
//当前值的下标+1
print(array.index(after: 1))//输入2
//当前值的下标-1
print(array.index(before: 1))//输出1
//给定一个索引+2
print(array.index(array.startIndex, offsetBy: 2))//输出2
//给定一个缩影+2 不超出最大索引
print(array.index(array.startIndex, offsetBy: 2, limitedBy: array.endIndex)!)//输出2
九、prefix与suffix方法
let array = [1,2,3,4]
print(array.prefix(2))//输出[1,2]
print(array.suffix(2))//输出[3,4]
print(array.prefix(upTo: 3))//输出[1,2,3]
print(array.suffix(from: 1))//输出[2,3,4]
十、dropFirst、dropLast方法
dropFirst返回的是除首元素之外的片段,dropLast返回的是除尾元素之外的片段
let array = [1,2,3,4]
print(array.dropFirst())//输出[2,3,4]
print(array.dropLast())//输出[1,2,3]
print(array.dropFirst(2))//输出[3,4]
print(array.dropLast(2))//输出[1,2]