Swift高阶函数是指可以接受函数作为参数或返回函数的函数。高阶函数强调了函数的参数和返回值都可以是函数类型,这使得函数能够被视为可传递和可组合的值和运算。
Swift中有多种高阶函数,包括map
,filter
,reduce
,sort
,flatMap
,compactMap
等。
1. Map
map
是高阶函数中最常用的函数之一。它接受一个函数和一个数组,并返回一个新数组,其中每个元素都是原始数组中对应元素通过输入的函数转换后得到的结果。
以下是一个简单示例,将一个数组中的每个元素加倍:
let numbers = [1, 2, 3, 4, 5]
let doubled = numbers.map { $0 * 2 }
print(doubled)
// prints [2, 4, 6, 8, 10]
2. Filter
filter
函数接受一个函数和一个数组,并返回一个新数组,其中只包含原始数组中符合条件的元素。这个函数可以用于过滤数组中不需要的元素。
以下是一个简单示例,从一个字符串数组中过滤出包含大写字母的字符串:
let words = ["apple", "banana", "CAT", "dog", "EGG"]
let capitalized = words.filter { word in
let pattern = ".*[A-Z]+.*"
let range = word.range(of: pattern, options: .regularExpression)
return range != nil
}
print(capitalized)
// prints ["CAT", "EGG"]
3. Reduce
reduce
函数接受一个函数和一个数组,并返回一个单一的值,这个值是通过使用指定的函数对数组中的所有元素进行聚合得到的。这个函数可以用于计算数组中所有元素的总和或平均值等。
以下是一个简单示例,计算一个数组中所有元素的总和:
let numbers = [1, 2, 3, 4, 5]
let sum = numbers.reduce(0, { $0 + $1 })
print(sum)
// prints 15
上面的例子在reduce
函数的初始化值参数中指定了一个初始值0,reduce
函数对该数组中的所有元素进行了求和操作。reduce
函数中的第二个参数是一个闭包,用于对数组中的每个元素进行操作。
4. Sorted
sorted
函数接受一个数组,并返回一个新数组,其中所有元素都按照指定的顺序排列。这个函数可以用于对数组中的元素进行排序操作。
以下是一个简单示例,对一个包含人员信息的数组按照年龄从小到大排序:
let people = [("Alice", 20), ("Bob", 18), ("Charlie", 25), ("David", 22)]
let sortedPeople = people.sorted { (person1, person2) in
return person1.1 < person2.1
}
print(sortedPeople)
// prints [("Bob", 18), ("Alice", 20), ("David", 22), ("Charlie", 25)]
在这个例子中,我们传递了一个闭包作为sorted
函数的参数,这个闭包用于比较元组中的第二个元素(年龄),成升序排列。
5. FlatMap
flatMap
接受一个数组,然后将每个元素映射为新的数组,并将所有结果组合成一个单一的数组。与map不同,在使用flatMap
时,元素可以映射到一个可选类型的数组,从而更加灵活。
以下是一个简单示例,将一个含有字符串的数组转换成一个包含所有单词的数组:
let phrases = ["hello world", "goodbye cruel world"]
let words = phrases.flatMap { $0.split(separator: " ") }
print(words)
// prints ["hello", "world", "goodbye", "cruel", "world"]
在这个例子中,首先使用split
函数将字符串分割成单词数组,然后使用flatMap
将多个数组合并为一个数组。
6. CompactMap
compactMap
通过一个闭包参数来转化数组中的每个元素,并返回一个新的数组,其中nil
值会被过滤掉。这个闭包必须返回一个可选类型值,当返回值为nil
时,元素将被过滤掉。
例如:
let items = [1, 2, 3, 4, 5]
let mappedItems = items.map { $0 * 2 }
print(mappedItems)
// prints [2, 4, 6, 8, 10]
let compactMappedItems = items.compactMap { $0 % 2 == 0 ? $0 : nil }
print(compactMappedItems)
// prints [2, 4]
在上面的例子中,我们将数组中的元素乘以 2 进行了映射,产生了一个新的数组。然后我们使用compactMap
过滤掉了奇数元素,只剩下了偶数元素 2 和 4。
One more Thing
Swift高阶函数的另一个强大之处在于它们可以链接在一起形成一个管道,这被称为函数链或函数式编程范式。使用函数链,我们可以通过将多个函数应用于同一个数组来生成一个复杂的、自定义的操作序列。
以下是一个简单示例,将一个字符串数组中的大写字母转换为小写字母,并按字母顺序排序:
let words = ["AbC", "deF", "ghi", "JKL"]
let result = words
.map { $0.lowercased() }
.filter { $0.count <= 3 }
.sorted()
print(result)
// prints ["abc", "def", "ghi"]
在这个例子中,我们调用了串联式的map
、filter
和sorted
函数,它们在一起形成了一个管道,每个函数都返回一个新的数组,以形成复合操作。
通过函数链,我们可以创建与原始数据完全不同的结果,并且所需的代码量非常少。使用高阶函数以及函数链编程方式,可以使代码更加可读性强,更加易于维护和测试。
总之,高阶函数是Swift语言中非常强大和灵活的工具,可以大大简化代码,并提高代码的可读性和可维护性。掌握这些高阶函数,可以让我们更快地构建高效、简洁的代码。