一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情。
将函数行为参数化
- map 和 CompactMap - 对元素进行变换
- filter - 筛选
- reduce - 将元素合并到一个总和的值
- squence - 下一个元素
- forEach - 对于一个元素执行怎样的操作
- sort,lexicographicCompare 和 partition - 两个元素应该以怎样的顺序进行排列
- first, firstIndex, contains - 元素是否符合某一个条件
- elementsEqual和starts - 俩个元素是否相等
- split - 这个元素是否是封割符
- prefix - 判断为真,将元素过滤出来,一旦不为真,就将剩余结果抛弃,和filter类似,但是会提前退出。这个函数在处理无限序列或者延迟家孙(lazily-computed)的时候非常有用
- drop - 判断为真,丢弃元素,一旦不为真,将剩余结果返回。和prefix(while:)相似,不过返回相反的集合
Filter
(1..<10).map { $0 * $0 }.filter { $0 % 2 == 0 } // [4, 16, 36, 64]
实现源码
extension Array {
func filter(_ isIncluded: (Element) -> Bool) -> [Element] {
var result: [Element] = []
for x in self where isIncluded(x) {
result.append(x)
}
return result
}
}
对于判断条件filter的性能比contains低,因为contains不会因为计数而去全新创建一个数组,并且一旦找到第一个元素就会退出
Reduce
所有值合并为新值
let sum = fibs.reduce(0) { total, num in total + num } // 12
fibs.reduce(0, +) // 12
输入的值和输出的值可以不同
print(array.reduce("") { str, num in str + "(num)," })
// 0,1,1,2,3,5
实现源码
extension Array {
func reduce<Result>(_ initialResult: Result,
_ nextPartialResult: (Result, Element) -> Result) -> Result
{
var result = initialResult
for x in self {
result = nextPartialResult(result, x)
}
return result
}
}
Reduce实现map和filter
extension Array {
func map2<T>(_ transform: (Element) -> T) -> [T] {
return reduce([]) {
$0 + [transform($1)]
}
}
func filter2(_ isIncluded: (Element) -> Bool) -> [Element] {
return reduce([]) {
isIncluded($1) ? $0 + [$1] : $0
}
}
}
For Each
对集合中每个元素调用一个函数,return不能返回到函数的作用域之外,他做的仅仅是从闭包中返回
array.forEach{
print($0)
if $0 > 2 {
return
}
print($0)
}
0
0
1
1
1
1
2
2
3
5
切片
通过下标获取元素
let slice = array[1...]
print(slice)
print(type(of: slice))
[1, 1, 2, 3, 5]
ArraySlice<Int>
切片类型ArraySlice只是一种表示方式,它的背后仍然是原来的数组。因为数组的元素不会被复制,所以创建一个切片的代价是很小的。
[图片上传失败...(image-8e753c-1635170375028)]
ArraySlice和Array都满足了相同的协议(当中最重要的是Collection协议),所以可以把切片当数组处理
let newArray = Array(slice)
type(of: newArray) // Array<Int>
如果是切片用startIndex 和 endIndex 属性做索引计算。