前言
这篇文章会列举下列方法的使用示例:
map和flatMap—— 对元素进行变换filter—— 只包含特定的元素allSatisfty—— 针对一个条件测试所有的元素reduce—— 将元素聚合成一个值sort(by),sorted(by:)—— 排序lexicographicallyPrecedes(_:by)—— 多参数排序elementsEqual(_:by:)和starts(with:by:)—— 将元素与另一个数组比较split(whereSeparator)—— 把所有元素分成多个数组prefix(while:)—— 从头取元素直到条件不成立drop(while:)—— 条件为真时丢弃元素,不为真则返回其余的元素(和prefix类似,不过返回相反的集合)removeAll(where)—— 删除所有符合条件的元素
map 和 flatMap
对元素进行变换。
// map
let arr = [1, 2, 3]
let brr = arr.map { "No." + String($0) }
// brr = ["No.1", "No.2", "No.3"]
// flatMap 第一种重载
let arr = [[1, 2, 3], [4, 5, 6]]
let brr = arr.flatMap { $0 }
// brr = [1, 2, 3, 4, 5, 6]
// 等价于
let brr = Array(arr.map { $0}.joined())
// flatMap 第二种重载
let arr: [Int?] = [1, 2, nil, 3, 4, nil, 5]
let brr = arr.flatMap { $0 }
// brr = [1, 2, 3, 4, 5]
fliter
只包含特定的元素。
let arr = [1, 2, 3]
let brr = arr.filter { $0 == 1 }
// brr = [1]
allSatisfty
针对一个条件测试所有的元素,全部元素都满足条件则返回 true,否则返回 false。
let arr = [1, 2, 3, 4]
print(arr.allSatisfy { $0 >= 3 } ) // false
print(arr.allSatisfy { $0 >= 1 } ) // true
reduce
将元素聚合成一个值。
let arr = [1, 2, 3, 4, 5]
print(arr.reduce(10, +)) // 25 等价于 10+1+2+3+4+5
let arr = ["a", "b", "cd"]
print(arr.reduce("", +)) // abcd 等价于 ""+"a"+"b"+"cd"
sort(by), sorted(by:)
排序。
// sort 修改原数组,没有返回值;sorted 不修改原数组,返回一个新数组
let sortArr = [3, 4, 5, 2, 1]
let sortBrr = sortArr.sorted { $0 < $1 } // [1, 2, 3, 4, 5]
根据两个参数进行排序:
// 需求,先按 firstName 排序,再按 lastName 排序
let sortModel_1 = CustomSortModel(firstName: "a", lastName: "a_x")
let sortModel_2 = CustomSortModel(firstName: "a", lastName: "b_x")
let sortModel_3 = CustomSortModel(firstName: "b", lastName: "a_x")
let sortModel_4 = CustomSortModel(firstName: "b", lastName: "b_x")
let sortModel_5 = CustomSortModel(firstName: "c", lastName: "a_x")
let sortModel_6 = CustomSortModel(firstName: "c", lastName: "b_x")
let sortModelArr =
[sortModel_5, sortModel_1, sortModel_4, sortModel_2, sortModel_6, sortModel_3]
let sortModelBrr = sortModelArr.sorted {
if $0.firstName != $1.firstName {
return $0.firstName < $1.firstName
}
else {
return $0.lastName < $1.lastName
}
}
// [sortModel_1, sortModel_2, sortModel_3, sortModel_4, sortModel_5, sortModel_6]
lexicographicallyPrecedes(_:by:)
多参数排序,上面的多参数排序例子可以使用这个方法进行简化:
let brr = sortModelArr.sorted {
let left = [$0.firstName, $0.lastName]
let right = [$1.firstName, $1.lastName]
return left.lexicographicallyPrecedes(right) { $0 < $1 }
}
// [sortModel_1, sortModel_2, sortModel_3, sortModel_4, sortModel_5, sortModel_6]
demo2: 比较两个字符串版本的大小:
let storeVersion = "1.13.10"
let currentVersion = "1.120.10"
let storeVersionArr = storeVersion.components(separatedBy: ".").map{ Int($0) ?? 0 }
let currentVersionArr = currentVersion.components(separatedBy: ".").map{ Int($0) ?? 0 }
// true
print(storeVersionArr.lexicographicallyPrecedes(currentVersionArr))
partition(by:)
符合条件的元素移动到最后,它不会保留原数组的顺序:
var partitionArr = [4, 3, 2, 5, 1, 3, 6, 2, 7]
let pIndex = partitionArr.partition { $0 > 3 }
// pIndex = 5
// partitionArr : [2, 3, 2, 3, 1, 5, 6, 4, 7]
// 需要注意的是它并不会进行排序
// 通过 prefix 或者 suiffx 取出
let head = partitionArr.prefix(upTo: pIndex)
let end = partitionArr.suffix(from: pIndex)
// head: [2, 3, 2, 3, 1]
// suffix: [5, 6, 4, 7]
elementsEqual(_:by:) 和 starts(with:by:)
将元素与另一个数组比较。
// elementsEqual(_:by:) 比较序列中每一个元素是否相等
let arr = [1, 2, 3, 4]
let arr_1 = [1, 2, 3, 4]
let arr_2 = [2, 1, 3, 4]
let set: Set = [1, 2, 3, 4]
print(arr.elementsEqual(arr_1)) // true
print(arr.elementsEqual(arr_2)) // false
print(arr.elementsEqual(set)) // false
// starts(with:by:)
let arr = [1, 2, 3]
let brr = [1, 2, 3, 4, 5]
print(brr.starts(with: arr)) // true
split(whereSeparator:)
把所有元素分成多个数组。
let arr = ["A", "B", "C", "D", "B"]
// 遍历数组,当元素满足条件时,进行切割,生成切片
let arrSlices = try arr.split(whereSeparator: { $0 == "B" })
print(arrSlices) // [ArraySlice(["A"]), ArraySlice(["C", "D"])]
prefix(while:) 和 drop(while:)
let arr = ["A", "B", "C", "D"]
print(arr.prefix(2)) // ["A", "B"]
print(arr.prefix(upTo: 2)) // ["A", "B"]
print(arr.prefix(through: 2)) // ["A", "B", "C"]
print(arr.dropFirst()) // ["B", "C", "D"]
print(arr.dropLast(2)) // ["A", "B"]
print(arr.suffix(2)) // ["C", "D"]
removeAll(where:)
删除所有符合条件的元素。
var arr = ["A", "B", "C", "D", "B"]
try arr.removeAll(where: { $0 == "B" })
print(arr) // ["A", "C", "D"]
结尾
Swift 封装这些函数的目的是为了让开发者摆脱代码中杂乱无趣的部分,让开发者能将重心放到真正想要表达的逻辑代码之中,所以在遇到数组相关的处理之前,先找一下有没有已经封装好的方法,是比较好的选择。
转载请注明 [出处](# 领略一下 Swift 数组的高阶函数)。