import UIKit
///内建集合类型
//Mark: 1、数组的可变性
let fibs = [0, 1, 1, 2, 3, 5]
//因为数组是值类型,并且let声明的是常量,所以编译器会强制保证数组的值不会改变
//fibs.append(8)
//标准库中的集合(数组,字典,集合)都是值类型,具有值语义,在赋值时会复制一份副本。 创建多个副本,可能会造成性能问题,在bswift标准库中使用了“写时赋值”技术,它能保证必要时对数据进行复制
var x = [1, 2, 3, 4]
var y = x
y.append(5)
print(x)
print(y)
//Foundation框架中,NSArray, NSMutableArray 是引用类型,即使声明为let,也无法保证值不会被修改
let a = NSMutableArray(array: [1, 2, 3])
let b: NSArray = a
a.insert(4, at: 3)
print(b)
var array = [1, 2, 3, 4]
//迭代数组,用for-in
for x in array {
print(x)
}
//剔除第一个元素, 返回值是一个ArraySlice 的对象,该对象的下标并不是从0开始,而是和数组起始和结束为止下标对应
var tem = array.dropFirst()
//tem.remove(at: 1)
print(tem)
//剔除最后一个, 返回值是一个Array对象,可以插入,删除 问题: 为什么dropFirst返回值是切片,而diropLast返回的是数组呢?
var tem2 = array.dropLast()
tem2.insert(0, at: 0)
print(tem2)
print(array)
for (index, element) in array.enumerated() {
print("\(index) .. \(element)")
}
// Mark: 2、数组变形
//map函数:对数组中的每个元素执行转换操作
var squared: [Int] = []
for fib in fibs {
squared.append(fib * fib)
}
print(squared)
//与上面写法相比:1、语法变短,逻辑更清晰,不用读for循环,2、省略变量声明,类型可以推断,不需要指明类型,3、创造map函数和上面代码部分类似
let squares = fibs.map { fib in fib * fib }
print(squares)
print(fibs)
//map函数实现原理
extension Array {
func map<T>(_ transform:(Element) -> T) ->[T] {
var result: [T] = []
for x in self {
result.append(transform(x))
}
return result
}
}
//使用函数作为参数,将核心逻辑封装在类中,可变逻辑抛到外面
extension Array {
func last1(where predicate: (Element) -> Bool) -> Element? {
for x in reversed() where predicate(x) {
return x
}
return nil
}
}
let re = array.last1 { (x) -> Bool in
x > 2
}
print(re == nil ? "" : re!)
//可变和带有状态的闭包
//下面这种做法是不推荐的:因为map函数是对数组的变形,而此处改变了table,所以不推荐
var table: [Int] = []
array.map { item in
table.append(item)
}
//闭包: 可以捕获自身作用域以外的变量的函数称为闭包
//map函数实现accumulate函数: 累加,累乘。。。
extension Array {
func accumulate1<Result>(_ initialResult: Result, _ nextPartialResult:(Result, Element) -> Result) -> [Result] {
var running = initialResult
return map { next in
running = nextPartialResult(running, next)
return running
}
}
}
array = [1, 2, 3, 4, 5]
let re1 = array.accumulate1(1, +)
// MARK: Filter 过滤:将数组中符合条件的元素过滤出来,生成一个新的数组
let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]
let re2 = nums.filter{ x in x % 2 == 0}
print(re2)
//map和filter组合使用: 求100以内同事满足是偶数,并且是平方数的数
let re3 = (0...10).map{ $0 * $0}.filter{ $0 % 2 == 0}
print(re3)
//filter的实现原理
extension Array {
func filter1(_ isInclude: (Element) -> Bool) -> [Element] {
var result: [Element] = []
for x in self where isInclude(x) {
result.append(x)
}
return result
}
}
let re4 = nums.filter1{ $0 > 5}
print(re4)
// 对于大型数组,尽量少用filter,因为会创建一个全新的数组,并且会对数组中的每个元素都操作
var bigArray = [0, 2, 3, 4, 5, 6]
bigArray.filter1{ $0 == 0 }.count > 0
//上述代码可以用contains函数代替,1、不会创建新数组,2、找到之后就结束
bigArray.contains(0)
extension Sequence {
//所有元素都满足条件 === 不存在元素不满足条件
public func all(maching predicate:(Element) -> Bool) -> Bool {
return !self.contains(where: !predicate($0))
}
}
//Mark: Reduce操作:合并值
fibs.reduce(0, +)
extension Array {
func reduce1<Result>(_ initialResulat: Result, nextPartialResult:(Result, Element) -> Result) -> Result {
var result = initialResulat
for x in self {
result = nextPartialResult(result, x)
}
return result
}
}
//reduce 实现map
extension Array {
func map2<T>(_ transform: (Element) -> T) -> [T] {
return reduce([], {
$0 + [transform($1)]
})
}
func filter2(_ predicate:(Element) -> Bool) ->[Element] {
return reduce([], {
predicate($1) ? $0 : $0
})
}
}
// Mark: flatMap 多维数组展平
let nestArray = [
[1, 3, 5, 7, 9],
[2, 4, 6, 8, 10]
]
let re5 = nestArray.joined()
for x in re5 {
print(x)
}
extension Array {
func flatMap1<T>(_ transform:(Element) -> [T]) -> [T] {
var result:[T] = []
for x in self {
result.append(contentsOf: transform(x))
}
return result
}
}
let suits = ["♠︎", "♥︎", "♣︎", "♦︎"]
let ranks = ["J", "Q", "K", "A"]
let result = suits.flatMap1 { suit in
ranks.map2({ rank in
(suit, rank)
})
}
print(result)
//forEatch:类似map,对每个元素执行特性操作,不同点:没有返回值, 注意forEach中的return不会打断循环
suits.forEach { print($0) }
网友评论