# Swift集合类高阶函数

``````// 全文的基础数据
let numbers = [7, 6, 10, 9, 8, 1, 2, 3, 4, 5]
``````
##### 1.sort函数

``````var sortArr = numbers
numbers.sort { a, b in
return a < b
}
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
``````

``````var sortArr2 = numbers
numbers.sort()
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
``````
##### 2.sorted函数

`sorted函数``sort函数`对应。

``````let sortedArr = numbers.sorted { a, b in
return a > b
}
// [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

// sorted()函数
let sortedArr2 = numbers.sorted()
// [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

// 闭包简写
let sortedArr3 = sortedArr2.sorted(by: >)
// [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
``````
##### 闭包的省略写法

``````numbers.sort(by: >)
// [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
``````

``````numbers.sorted { (a: Int, b: Int) -> Bool in
return a > b
}
``````

``````numbers.sorted { (a: Int, b: Int) in
return a > b
}
``````

``````numbers.sorted { a, b in
return a > b
}
``````

``````numbers.sorted { return \$0 > \$1 }
``````

``````numbers.sorted { \$0 > \$1 }
``````

``````numbers.sorted(by: >)
``````
##### 3.map函数

``````// 数组数值转换为其各自平方
let mapArr = numbers.map { \$0 * \$0 }
// [49, 36, 100, 81, 64, 1, 4, 9, 16, 25]
``````
##### 可选类型的 map, flatMap函数

``````let num1: Int? = 3
let num2: Int? = nil

let numMap1 = num1.map {
\$0 * 2
}
numMap1              // 6
type(of: numMap1)    // Optional<Int>.Type

let numMap2 = num2.map {
\$0 == 0
}
numMap2              // nil
type(of: numMap2)    // Optional<Bool>.Type

let numFlatMap1 = num1.flatMap {
\$0 * \$0
}
numFlatMap1              // 9
type(of: numFlatMap1)    // Optional<Int>.Type

let numFlatMap2 = num2.flatMap {
\$0 == 0
}
numFlatMap2              // nil
type(of: numFlatMap2)    // Optional<Bool>.Type
``````

``````func loadURL(url: URL) {
print(url.absoluteString)
}

let urlStr: String? = "https://github.com/wangyanchang21"
guard let siteStr = urlStr else {
assert(false)
}
guard let url = URL(string: siteStr) else {
assert(false)
}
``````

``````// 这行优雅的代码代替上面的代码
``````

``````// compile error
``````

``````let date: Date? = Date()
let format = date.map(DateFormatter().string)
``````

##### 4.flatMap函数

``````let optLatticeNumbers = [[1, Optional(2), 3], [3, nil, 5], nil]
// 解析首层元素, 若有nil则过滤, 就不会降维
let flatMapArr2 = optLatticeNumbers.flatMap { \$0 }
// [[1, 2, 3], [3, nil, 5]]
``````

``````let latticeNumbers = [[1, Optional(2), 3], [3, nil, 5]]
// 解析首层元素, 若没有nil, 则会降维
let flatMapArr = latticeNumbers.flatMap { \$0 }
// [1, 2, 3, 3, nil, 5]
``````

##### 5.compactMap函数

Swift4.1开始开放的一种映射函数，会解析并过滤首层元素为`nil`的元素。

``````let compactMapArr = optLatticeNumbers.compactMap { \$0 }
// [[1, 2, 3], [3, nil, 5]]
let compactMapArr2 = latticeNumbers.compactMap { \$0 }
// [[1, 2, 3], [3, nil, 5]]
``````

`compactMap`函数作为过滤`nil``flatMap`函数的替代函数。当集合中的元素为一个一维集合，他们之间的功能是没有差别的。

``````let flatNumbers = [1, Optional(2), 3, nil, Optional(5), nil]

let flatMapArr = latticeNumbers.flatMap { \$0 }
// [1, 2, 3, 5]
let compactMapArr = optLatticeNumbers.compactMap { \$0 }
// [1, 2, 3, 5]
``````
##### 6.filter函数

``````let filterArr = numbers.filter { num in
return num < 3 || num > 8
}
// [10, 9, 1, 2]
``````
##### 7.reduce函数

``````let reduceNumber = numbers.reduce(100) { result, num in
return result + num
}
// 155

let reduceString = ["C", "O", "D", "E"].reduce("word: ") { result, num in
return result + num
}
// "word: CODE"
``````
##### 8.prefix函数

``````let prefixArr = numbers.prefix { \$0 < 10 }
// [7, 6]
``````

`prefix`相关函数：
`upTo`: 正向取元素创建数组, 包含小于指定index的元素

``````let prefixUpToArr = numbers.prefix(upTo: 5)
// [7, 6, 10, 9, 8]
``````

`through`: 正向取元素创建数组, 包含小于等于指定index的元素

``````let prefixThroughArr = numbers.prefix(through: 2)
// [7, 6, 10]
``````

`maxLength`: 正向取元素创建数组, 包含指定的元素个数

``````let prefixMaxLengthArr = numbers.prefix(6)
// [7, 6, 10, 9, 8, 1]
``````
##### 9.drop函数

`prefix`函数对应。正向跳过满足条件的元素，进行新集合创建。一旦出现不满足条件的元素，则跳出循环，不再执行。

``````let dropArr = numbers.drop { \$0 < 10 }
// [10, 9, 8, 1, 2, 3, 4, 5]
``````

`drop`相关函数：
`dropFirst`: 正向跳过元素创建数组, 跳过指定元素个数, 缺省值为1

``````let dropFirstArr = numbers.dropFirst(3)
// [7, 6, 10, 9, 8]
``````

`dropLast`: 返向跳过元素创建数组, 跳过指定元素个数, 缺省值为1

``````let dropLastArr = numbers.dropLast(5)
// [7, 6, 10, 9, 8]
``````
##### 10.first函数

``````let first = numbers.first { \$0 < 7 }
// 6
``````
##### 11.last函数

`first`函数对应。反向找出第一个满足条件的元素。

``````let last = numbers.last { \$0 > 5 }
// 8
``````
##### 12.firstIndex函数

``````let firstIndex = numbers.firstIndex { \$0 < 7 }
// 1
``````
##### 13.lastIndex函数

``````let lastIndex = numbers.lastIndex { \$0 > 5 }
// 4
``````
##### 14.partition函数

``````var partitionNumbers = [20, 50, 30, 10, 40, 20, 60]
let pIndex = partitionNumbers.partition { \$0 > 30 }
// partitionNumbers = [20, 20, 30, 10, 40, 50, 60]
// pIndex = 4
``````
##### 15.min函数

``````let min = numbers.min { \$0 % 5 < \$1 % 5 }
// 10
``````

`min()`函数，自然升序取最小。

``````let minDefault = numbers.min()
// 1
``````
##### 16.max函数

``````let maxDictionary = ["aKey": 33, "bKey": 66, "cKey": 99]
let max = maxDictionary.max { \$0.value < \$1.value }
// (key "cKey", value 99)
``````

`max()`函数，自然升序取最大。

``````let maxDefault = numbers.max()
// 10
``````
##### 17.removeAll函数

``````var removeArr = numbers
removeArr.removeAll { \$0 > 6 }
// [6, 1, 2, 3, 4, 5]
``````
##### 18.集合遍历

`forEach`函数：

``````numbers.forEach { num in
print(num)
}
``````

`for-in`函数:

``````for num in numbers where num < 5 {
print(num)
}
``````

`enumerated()`函数配合使用：

``````for (index, num) in numbers.enumerated() {
print("\(index)-\(num)")
}
``````

##### 19.shuffled函数

`shuffled`函数，打乱集合中元素的的顺序。

``````let ascendingNumbers = 0...9
let shuffledArr = ascendingNumbers.shuffled()
// [3, 9, 2, 6, 4, 5, 0, 1, 7, 8]
``````
##### 20.contains函数

`contains`函数，判断集合中是否包含某元素。

``````let containsBool = numbers.contains(8)
let containsBool1 = numbers.contains(11)
// true
// false
``````
##### 21.split和joined函数

`split`函数，字符串的函数，按条件分割字符串，为子字符串创建集合。与`Objective-C`中的`componentsSeparatedByString:`方法类似。

``````let line = "123Hi!123I'm123a123coder.123"
let splitArr = line.split { \$0.isNumber }
// ["Hi!", "I'm", "a", "coder."]

// 也可指定字符
let splitArr2 = line.split(separator: "1")
// ["23Hi!", "23I'm", "23a", "23coder.", "23"]
``````

`joined`函数，数组元素连接指定字符拼接成一个字符串。与`Objective-C`中的`componentsJoinedByString:`方法类似。

``````let joined = splitArr.joined(separator: "_")
// "Hi!_I'm_a_coder."

// 也可以只传入字符
let joined2 = splitArr2.joined(separator: "#")
// "23Hi!#23I'm#23a#23coder.#23"
``````
##### 22.zip函数

``````let titles = ["aaa", "bbb", "ccc"]
let numbers = [111, 222, 333]
let zipA = zip(titles, numbers)
for (title, num) in zipA {
print("\(title)-\(num)")
}
``````

``````aaa-111
bbb-222
ccc-333
``````