swift中数组 *** 作

swift中数组 *** 作,第1张

swift内部对于数组重新赋值的时候,这个时候不会发生copy *** 作,仅当 *** 作时才会进行把原来数组的值复制到新数组中

对于数组中的元素按照某种规则进行筛选

作用是将两个序列的元素,一一对应合并生成一个新序列。一般不会单独使用,而是会和其它的方法配合使用。

自定义实现类似功能,例如找出二维数组中相邻元素(相邻元素放入数组中)

swift中的extension与OC的category有点类似,但extension比起category更加强大和灵活,不仅仅可以同时扩展某种类型或结构体的方法,也可以protocol等结合使用

一般用来对所有元素的 *** 作,例如进行单独运算或者统一转换类型等

如果你想要对集合中的每个元素都调用一个函数的话,使用 forEach 会比较合适。但是在for each中的return 语句并不会终止循环,它做的仅仅是从闭包中返回,因此在 forEach 的实现中会开始下一个循环的迭代。

“切片和它背后的数组是使用相同的索引来引用元素的。因此,切片索引不需要从零开始”,可以使用“startIndex 和 endIndex 属性做索引计算”

Array是一种有序的,可以随机访问的数据结构,可以存储任意的数据类型。

1、使用数组下标访问相应的元素:

下标越界时会导致运行错误

2、使用  for-in 遍历数组元素

3、使用 .first 和 .last 访问数组的第一个元素和最后一个元素

返回值是Optional类型

4、使用 .isEmpty 判断数组是否为空

.append 在数组的末尾添加一个新元素

.append(contentsOf:) 在数组的末尾添加别的数组或序列中的多个值

.insert(_:at:) 在指定位置插入单个元素

.insert(contentsOf:at:)  在指定位置插入别的数组或序列中的多个值

插入 *** 作导致插入位置后面的元素发生移动,时间复杂度为O(n)

.remove(at:) 删除指定位置的元素

.removeSubrange(_:) 删除某个范围内所有的元素

.removeLast() 删除最后一个元素

删除 *** 作导致删除元素后面的元素发生移动,时间复杂度为O(n)

使用数组下标对相应位置的元素进行赋值

Swift为Array分配一段特定大小的内存空间,每当Array的内存空间用完时,Swift就为该Array分配一段大小为原来的两倍的内存空间,并将Array的元素复制到新的内存空间中。开辟新的存储空间和复制元素需要额外的开销,但Swift的内存大小指数增长的策略使得 append *** 作所花费的平均时间约为一常量(随着数据的增加,开辟新内存的需求会变少),优化了性能。

.reserveCapacity(_:) 

如果可以预知Array所需存储的数据的数量,可以使用上述函数为Array预留指定大小的内存空间(最小所需空间),从而避免内存空间指数增长所造成的浪费

使用Array时,所占用的内存是连续的,而使用NSArray,所占用的内存并不一定是连续的(NSArray为引用类型),所以在OC中使用Array时,底层可能使用NSArray或NSArray的子类作为Array的存储,从而不能保证Array的使用效率。

当Array中保存的数据为值类型时,修改单一副本的值并不会引起其他副本的变化

但当Array中保存的数据为引用类型时,修改单一副本的值会引起其他副本的变化

因为新的副本被创建时,仅存储的对象指针被复制,并没有创建新的对象

Array也采取了Copy-On-Write(COW)的优化策略,多个副本共享一段存储区,仅当某一副本被修改时,才为该副本开辟新的存储区,复制原Array到新的内存,并在该新的内存位置进行修改。

如果Array只有一个副本,对该副本的 *** 作还是在相同的内存位置进行的(in place)。

在上述例子中,numbers拥有两个副本,这两个副本共享numbers的存储空间,当numbers被修改时,新的内存被开辟,原Array被复制到新的内存中,对numbers的后续修改都在该新内存中进行(in place),而原先的两个副本继续共享原本的存储空间。

使用类型转换 as 进行 NSArray 和 Array之间的桥接

为了确保桥接的成功,Array中的数据类型必须是class,@objc protocol或者是能与Foundation中的类型相桥接的类型(String)。

在上述例子中,String可以桥接到NSString,所以Array<String>可以被桥接到NSArray, 但String?不能被桥接到Foundation中的类,所以Array<String?>也不能桥接到NSArray。

如果Array中的数据类型为class或@objc protocol,Array桥接到NSArray的时间复杂度和空间复杂度为O(1),否则为O(n)。

如何NSArray中的数据类型为class或@objc protocol,NSArray桥接到Array会首先调用数组的copy(with:)方法,获取不可修改的副本--时间复杂度不可估计,并进行额外的统计工作--O(1),如果NSArray已经是不可修改的,copy(with:)方法返回同一个数组--O(1),如果返回的是同一个数组,那么NSArray和Array共享同一段内存,并采用copy-on-write进行优化。

如果NSArray中的数据类型是Foundation中的类型,NSArray桥接到Array时需要数据元素复制到连续的内存中--O(n),进一步访问Array中的元素不需要桥接。

ContiguousArray  和 ArraySlice 类型不会被桥接,因为这两种类型的对象所占用的内存总是连续的。

苹果官方文档

数组是一个可以存放相同类型的多个元素对象的有序线性列表,这些元素可以是任意类型,也可以是元组。但是如果在一个数组中出现在了与其他元素类型不同的元素,那么编译器就会报错。

swift 中还提供了+ *** 作符,可以把两个数组拼接在一起,组成一个新的数组。

数组对象的元素访问:如果访问指定元素,可以通过下标 *** 作符[]来获得,若索引值超出了数组本身大小,那么程序会引发异常

count:获取数组个数

isEmpty:判断数组是否为空

contains( :):判断数组是否包含某个元素

append( :):在该变量数组最后面添加元素

insert(_:at:):在该变量数组指定位置添加元素,原本的元素被移动到新元素后面

remove(at:):在该变量数组中移除指定位置的元素

注意:数组字面量(例如:[1,2,3]),本身是一个常量,如果我们对数组字面量进行添加等 *** 作,则会引起编译器报错。

一个集合也能存放多个相同类型的元素,与数组不同的是:

1:一个集合不允许出现两个相同的元素

2:集合中的元素是无序的

3:并不是所有的类型对象都能作为集合的元素,不过swift的基本类型都可以

元素集合的访问不能像数组通过索引值,因为它是无序的,可以通过for-in循环,也可以通过flatMap方法,有选择性的将集合元素取出。

count:获取集合个数

isEmpty:判断集合是否为空

contains( :):判断集合是否包含某个元素

insert( :at:):在该变量集合指定位置添加元素,如以存在,原本的元素被覆盖,保证唯一性

remove(at:):在该变量集合中移除指定位置的元素

字典与数组和集合不同,它是以一种键-值对的形式存储元素的,字典中不允许出两个相同的键,但是不同的键可以对应相同的值,字典的元素也是无序的。字典中键的类型与值的类型都是在声明中直接确定的,每个键的类型应该一致,每个值的类型也应该一致,键的类型和值的类型可以相同也可以不同。

对字典的值的访问类似于数组对元素的访问,可以通过下标 *** 作符对字段的值进行访问,例如对于一个这样的字典对象dict[String :Int],我们可以通过dict["String"] 的方式来访问键“String”对应的值,不过这里得到的值是一个Optional对象,因为如果指定的键对应的值不存在,会返回空。

count: 获取字典的键值对元素个数

isEmpty:判断字典是否为空

keys:获取字典对象的所有键值

values:获取字典对象的所有值

updateValue(_:forKey:):更新一个键对应的值

removeValue(forKey:): 将指定的键的元素移除

注意:这里的keys和values返回的类型为LazyMapCollection,它与集合类型类似,不能通过下标访问元素,一般通过for-in循环迭代访问;变量字典还能通过调用下标方式来新增一个键值对或修改一个键对应的值。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11768589.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-18
下一篇 2023-05-18

发表评论

登录后才能评论

评论列表(0条)

保存