Map
map函數(shù)能夠被數(shù)組調(diào)用检访,它接受一個閉包作為參數(shù),作用于數(shù)組中的每個元素仔掸。閉包返回一個變換后的元素脆贵,接著將所有這些變換后的元素組成一個新的數(shù)組
1. 比如我們有一個這樣的需求遍歷一個數(shù)組中所有的元素,將每個元素自身與自身相加嘉汰,最后返回一個保存相加后元素的數(shù)組(-_-原諒我這表達(dá)能力,下面用代碼闡述)
如果我們不使用map函數(shù)丹禀,那么代碼如下
let numbers = [1,2,3]
var sumNumbers = [Int]()
for var number in numbers {
number += number
sumNumbers.append(number)
}
// [2,4,6]
print(sumNumbers)
可以看到上面的代碼正是我們經(jīng)常用到的代碼,但通過數(shù)組的map函數(shù)可以幫我們簡化上面的代碼
// 可以看到我們甚至可以不再定義可變的數(shù)組直接用不可變的就可以
let numbers = [1,2,3]
let sumNumbers = numbers.map { (number: Int) -> Int in
return number + number
}
// 下面介紹簡便寫法 因?yàn)閙ap閉包里面的類型可以自動推斷所以可以省略
let sumNumbers1 = numbers.map { number in
return number + number
}
// 可以省了return 但是循環(huán)次數(shù)多了一次 目前不知道這是什么原因(循環(huán)次數(shù)是3次這是4次) 結(jié)果是一樣的 <如果哪位大神知道麻煩告明小弟>
let sumNumbers2 = numbers.map { number in number + number }
print(sumNumbers2) // [2,4,6]
// 最終簡化寫法
let sumNumbers3 = numbers.map { $0 + $0 }
2. Map函數(shù)返回?cái)?shù)組的元素類型不一定要與原數(shù)組相同
let fruits = ["apple", "banana", "orange", ""]
// 這里數(shù)組中存在一個""的字符串 為了后面來比較 map 和 flatMap
let counts = fruits.map { fruit -> Int? in
let length = fruit.characters.count
guard length > 0 else {
return nil
}
return length
}
// [Optional(5), Optional(6), Optional(6), nil]
print(counts)
3. Map還能返回判斷數(shù)組中的元素是否滿足某種條件的Bool值數(shù)組
let array = [1,2,3,4,5,6]
// 最潔簡的寫法
let isEven = array.map { $0 % 2 == 0 }
// 這里在寫下完成的寫法 下面的例子 將都采用最潔簡的寫法^_^ 同時也要養(yǎng)成習(xí)慣看見上面那種潔簡的寫法 就要懂它做了些什么 會有什么樣的結(jié)果
let isEven1 = array.map { num in
// 寫上retrun在Playground中的循環(huán)次數(shù)是6次 不寫是7次 Xcode版本是7.2(7C68)
// 不知道這是不是bug 有知道的提醒下我~
return num % 2 == 0
}
// [false, true, false, true, false, true]
print(isEven)
FlatMap
flatMap 與 map 不同之處是
flatMap返回后的數(shù)組中不存在 nil 同時它會把Optional解包;
flatMap 還能把數(shù)組中存有數(shù)組的數(shù)組 一同打開變成一個新的數(shù)組 ;
flatMap也能把兩個不同的數(shù)組合并成一個數(shù)組 這個合并的數(shù)組元素個數(shù)是前面兩個數(shù)組元素個數(shù)的乘積
1. flatMap返回后的數(shù)組中不存在nil 同時它會把Optional解包
let fruits = ["apple", "banana", "orange", ""]
let counts = fruits.flatMap { fruit -> Int? in
let length = fruit.characters.count
guard length > 0 else {
return nil
}
return length
}
// [5,6,6]
print(counts)
2. flatMap 還能把數(shù)組中存有數(shù)組的數(shù)組 一同打開變成一個新的數(shù)組(看代碼秒懂_)
let array = [[1,2,3], [4,5,6], [7,8,9]]
// 如果用map來獲取新的數(shù)組
let arrayMap = array.map { $0 }
// [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(arrayMap)
// 用flatMap
let arrayFlatMap = array.flatMap { $0 }
// [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(arrayFlatMap)
3. flatMap也能把兩個不同的數(shù)組合并成一個數(shù)組 這個合并的數(shù)組元素個數(shù)是前面兩個數(shù)組元素個數(shù)的乘積
// 這種情況是把兩個不同的數(shù)組合并成一個數(shù)組 這個合并的數(shù)組元素個數(shù)是前面兩個數(shù)組元素個數(shù)的乘積
let fruits = ["apple", "banana", "orange"]
let counts = [1, 2, 3]
let fruitCounts = counts.flatMap { count in
fruits.map { fruit in
// title + "\(index)"
// 也可以返回元組
(fruit, count)
}
}
// [("apple", 1), ("banana", 1), ("orange", 1), ("apple", 2), ("banana", 2), ("orange", 2), ("apple", 3), ("banana", 3), ("orange", 3)]
print(fruitCounts)
// 這種方法估計(jì)用的很少 可以算是一個 flatMap 和 map 的結(jié)合使用吧
Filter
filter 可以取出數(shù)組中符合條件的元素 重新組成一個新的數(shù)組
filter可以很好的幫我們把數(shù)組中不需要的值都去掉 這個很贊鞋怀!
let numbers = [1,2,3,4,5,6]
let evens = numbers.filter { $0 % 2 == 0 }
// [2, 4, 6]
print(evens)
Reduce
map,flatMap和filter方法都是通過一個已存在的數(shù)組双泪,生成一個新的、經(jīng)過修改的數(shù)組密似。然而有時候我們需要把所有元素的值合并成一個新的值 那么就用到了Reduce
1. 比如我們要獲得一個數(shù)組中所有元素的和
let numbers = [1,2,3,4,5]
// reduce 函數(shù)第一個參數(shù)是返回值的初始化值
let sum = numbers.reduce(0) { $0 + $1 }
// 這里我寫下完整的格式
let sum1 = numbers.reduce(0) { total, num in
// 這里寫不寫return在Playground都循環(huán)5次 但上面用最潔簡的方法顯示循環(huán)6次焙矛。。残腌。 What The Fuck 這是什么鬼4逭濉!抛猫!
return total + num
}
// 15
print(sum)
2. 合并成的新值不一定跟原數(shù)組中元素的類型相同
let numbers = [1,5,1,8,8,8,8,8,8,8,8]
// reduce 函數(shù)第一個參數(shù)是返回值的初始化值
let tel = numbers.reduce("") { "\($0)" + "\($1)" }
// 15188888888
print(tel)
3. ruduce 還可以實(shí)現(xiàn) map 和 filter 并且時間復(fù)雜度變?yōu)镺(n) 原來 map 和 filter 的時間復(fù)雜度是O(n*n)
extension Array {
func mMap<U> (transform: Element -> U) -> [U] {
return reduce([], combine: { $0 + [transform($1)] })
}
func mFilter (includeElement: Element -> Bool) -> [Element] {
return reduce([]) { includeElement($1) ? $0 + [$1] : $0 }
}
}
本人對泛型的研究還很淺顯蟆盹,后續(xù)我會寫一篇關(guān)于Swift范型的文章,歡迎大家關(guān)注 -> MelodyZhy