swift基础教程——数组和字典

/*

复制,再编辑,自己留着看

*/

Swift 提供两种集合类型来存储集合,数组和字典。数组是一个同类型的序列化列表集合。字典是一个能够使用类似于键的唯一标识符来获取值的非序列化集合。

//看起来字典非常像map

在Swift中,数组和字典的键和值都必须明确它的类型。这意味这数组和字典不会插入一个错误的类型的值,以致于出错。

这也意味着当你在数组和字典中取回数值的时候能够确定它的类型。

注意:
Swift的数组 储存不同的类型会展示出不同的行为,例如变量,常量或者 函数和方法。更多的信息参见Mutability of Collections and Assignment 和 Copy Behavior for Collection Types.

1、数组
数组是储存同类型不同值的序列化列表。同样的值可以在数组的不同位置出现多次。

Swift数组是储存确定的值,这个Objective-C中的NSArray和NSMutableArray类是有区别的。因为它们是储存各种的对象,而且并不提供返回任何有关对象的具体信息。在Swift中,无论是确定的声明,还是隐式的声明,数组是非常确定它自身是储存什么样的类型,而且,它并不一定要求储存的是类对象。所以Swift数组是类型安全的,因为它一直都确定它自身所能包含的值

数组的简略语法
定义数组的完整写法是Array<SomeType>。其中SomeType是你想要包含的类型。你也可以使用类似于SomeType[]这样的简略语法。虽然这两种方法在功能上是相同的。但是我们更推荐后者,而且它会一直贯穿于本书。

//就像在android(java语言)中声明一个数组一样顺手。

数组实量(Array Literals)
你可以用一个数组实量(Array Literals)来初始化一个数组,它是用简略写法来创建一个包含一个或多个的值的数组。一个数组实量(Array Literals)是由它包含的值,“,”分隔符 已经包括以上内容的中括号对“[]”组成:

1
[ value 1 , 2 3 ]

下面的例子创建一个叫shoppinglist,储存字符串(String)类型的数组。

1
2
var shoppingList : String[] = "Eggs" "Milk" ]
/ 使用两个初始化参数来初始化shoppingList

shoppinglist变量被定义为字符串(String)类型的数组,写作String[]。因为这个数组被确定为字符串类型(String),所以它只能储存字符串(String)类型的值。在这里,用两个字符串类型的值(”Eggs” and “Milk”)和数组实量(Array Literals)的写法来初始化shoppingList数组。

注意:
shoppingList数组是被定义为一个变量(使用var 标识符)而不是常量(使用let 标识符),所以在下面的例子可以直接添加元素。

在这个例子中,数组实量(Array Literals)只包含两个字符串类型的值,这符合了shoppingList变量的定义(只能包含字符串(String)类型的数组),所以被分配的数组实量(Array Literals)被允许用两个字符串类型的值来初始化。

得益于Swift的类型推断,当你用相同类型的值来初始化时,你可以不写明类型。初始化shoppingList可以用下面这个方法来代替。

Milk"]

因为数组实量(Array Literals)中所有的值都是同类型的,所以Swift能够推断shoppingList的类型为字符串数组(String[])。

读取和修改数组
你可以通过方法和属性,或者下标来读取和修改数组。

通过只读属性count来读取数组的长度;

println("The shopping list contains \(shoppingList.count) items.")
prints "The shopping list contains items .”

通过一个返回布尔类型的isEmpty属性检查数组的长度是否为0

2
3
4
if shoppingList.isEmpty {
println "The shopping list is empty." } else {
"The shopping list is not empty." )
}
prints "The shopping list is not empty."

在数组末尾增加一个元素可以通过append方法

shoppingList.append"Flour"shoppingList 现在包含3个元素

甚至,还可以用(+=)操作符来把一个元素添加到数组末尾

shoppingList+"Baking Powder"
4 你也可以用(+=)操作符来把一个数组添加到另一个数组的末尾

"Chocolate Spread""Cheese""Butter"7 从数组中取出一个值可以使用下标语法。如果你知道一个元素的索引值,你可以数组名后面的中括号中填写索引值来获取这个元素

var firstItemshoppingList[0firstItem 等于 “Eggs"

注意,数组的第一个元素的索引值为0,不为1,Swift的数组总是索引0;

你可以使用下标语法通过索引修改已经存在的值。

]"Six eggs"
列表中的第一个值等于 "Six eggs" 而不等于 “Eggs"

你可以使用下标语法一次性改变一系列的值,尽管修改的区域远远大于要修改的值。在下面的例子中, 替换掉 “Chocolate Spread”,“Cheese”,”Butter”,”Bananas”,”Apples”:

4...6"Bananas""Apples" 注意,你不能使用下标语法在数组中添加一个元素,如果你尝试使用下标语法来获取或者设置一个元素,你将得到一个运行时的错误。尽管如此,你可以通过count属性验证索引是否正确再使用它。当count为0时(意味着数组为空),则count-1超出了索引的有效范围,因为数组的索引总是从0开始。

//实话说,我觉得上面的译文很怪异,数组索引范围从0开始,那么索引的范围就是[0,count-1],小于0或者大于count-1就是越界了,置于所谓的”你不能使用下标语法在数组中添加一个元素“,是现有数组大小,再有索引的(也就是下标),想要用下标去扩展大小自然不现实。而在确定了范围的前提下,你可以放心大胆的用下标去获取、修改一个元素,当然、修改需要类型一致。

在一个特定的索引位置插入一个值,可以使用insert(atIndex:)方法

3
shoppingList.insert "Maple Syrup" atIndex 个元素
在数组的第一位

这里调用insert方法指明在shoppingList的索引为0的位置中插入一个新元素 “Maple Syrup”

同理,你可以调用removeAtIndex方法移除特定的元素。这个方法移除特定索引位置的元素,已经返回这个被移除的元素(尽管你并不关心这个返回值)。

let mapleSyrupshoppingList.removeAtIndex索引位置为的元素被移除
个元素 不包括 Maple Syrup
mapleSyrup 常量等于被移除的 字符串

当元素被移除的,数组空缺的位置将会被填补,所以现在索引位置为0的元素再一次等于”Six eggs”:

firstItemfirstItem 现在等于 "Six eggs”

如果你从数组中移除最后一个元素,使用removeLast方法比removeAtIndex更方便,因为后者需要通过count属性计算数组的长度。和removeAtIndex方法一样,removeLast会返回被移除的元素。

let applesshoppingList.removeLast元素的最后一个元素被移除
5 个元素,不包括 cheese
apples 常量 现在等于被移除的 string

遍历数组
可以使用for-in循环来遍历数组中的值

4
5
6
7
for item in shoppingList }
Six eggs
Milk
Flour
Baking Powder
Bananas

如果需要每一个元素的整形的索引值,使用enumerate函数代替会更方便,enumerate函数对于每一个元素都会返回一个包含元素的索引和值的元组(tuple)。你可以在遍历部分分解元祖并储存在临时变量或者常量中。

index)in enumerate"Item \(index + 1): \(value)"元素2 如需更多for-in 循环信息,参见 For Loops.

//反正我看了总觉得这个像是介于数组和list之间的一个东西,或者说更像一个list。


创建和初始化数组
创建一个空的数组和确定的类型(不包含初始化值)使用的初始化语法:

var someIntsInt[]"someInts is of type Int[] with \(someInts.count) items."prints "someIntsisof type Int[]with 注意,someInt变量被确定为Int[],因为它使用生成Int[]的初始化方法。

或者,如果上下文(context)已经提供类型信息,例如函数参数或者已经确定类型的常量和变量,你可以从空的数组实量(Array Literals)创建一个空数组,写作[](空的中括号对)。

someInts.appendsomeInts 现在包含个Int型的元素
someInts []
someInts 现在是一个空的数组 但是类型仍然为Int[];

Swift数组类型也提供初始化方法来创建确定长度和提供默认数值的数组。你可以通过这个初始化方法增加一个新的数组,元素的数量成为count,合适的默认值为repeatedValue

var threeDoublesDouble[]countrepeatedValue0.0threeDoubles 的类型为 Double[]以及等于 [ 得益于类型推断,你并不需要指明这个数组储存的类型就能使用这个初始化方法,因为它从默认值中就能推断出来。

var anotherThreeDoublesArray2.5anotherThreeDoubles 被推断为 Double[] 最后,你可以使用(+)操作符就能创建一个新的数组,把两个存在的数组添加进来
这个新的数组类型从你添加的两个数组中推断出来

var sixDoublesthreeDoublesanotherThreeDoubles
sixDoubles 被推断为 Double[] 并等于 [ 2、字典

字典是储存同一类型但是不同值的容易。每一个值都对应这一个唯一的键(Key),就像是字典内的每一个值都有一个标识符。和数组内的元素是由区别的,字典内的元素是没有特殊的序列的。当你需要根据标识符来查找批量的值时,就可以使用字典。同样的,真实
的物品字典常常用来当作查找特定字典的标识符。

Swift字典时储存一个类型的具体的键和值,和Objective-C的NSDictionary 和NSMutableDictionary由一定的区别,因为它们是使用各种的对象来作为它们的键和值,而且并不提供任何有关对象的具体信息。在Swift中,对于一个特定的字典,它所能储存的键和值都是确定的,无论是明确声明的类型还是隐式推断的类型。

Swift的字典写法是Dictionary<KeyType,ValueType>,KeyType是你想要储存的键,ValueType是你想要储存的值。

//这里让我想到了java中这样一句话啊: Map<KeyType,ValueType> mMap = new hashMap<KeyType,ValueType>();

唯一的限制就是KeyType必须是可哈希的(hashable)——就是提供一个形式让它们自身是独立识别的。Swift的所有基础类型(例如字符串(String),整形(Int),双精度(Double)和布尔(Bool))在默认是可哈希的(hashable),和这些类型都常常用语当作字典的键。枚举成员值不需要协助值(associated values)(具体描述在 Enumerations)也是因为它们默认也是可哈希的(hashable)。

字典实量(Dictionary Literals)
你可以直接用一个字典实量(Dictionary Literals)初始化一个字典。和前面定义一个数组实量(Array Literals)的语法一样。字典实量(Dictionary Literals)就是使用简略写法直接写一个或者多个的键值对来定义一个字典。

一个键值对是一个键和值的组合。在字典实量(Dictionary Literals)里面,每一个键值对总是用一个冒号把键和值分割。键值对的写法就想是一个列表,使用逗号分割,并被一对中括号[]包含着:

key 1 在下面的例子,将会创建一个字典来储存国际机场的名字。在这个字典里面,键是三个字的国际航空运送协会代码,以及它的值是机场的名称:

var airportDictionary<String> ["TYO""Tokyo""DUB":"Dublin"]

airport字典被定义为一个类型为Dictionary<String,String>,这意味这,这个字典的键类型是字符串String,和它的值的类型也是String。

注意
airport字典是被定义为一个变量(使用var 标识符)而不是常量(使用let 标识符),所以在下面的例子可以直接添加元素。

airport字典使用一个包含两个键值对的字典实量(Dictionary Literals)来初始化。第一对由一个叫“TYO”的键和一个叫“Tokyo”的值,第二对有一个叫“DUB”的键和一个叫“Dublin”的值。

这个字典实量(Dictionary Literals)包含两个字符串(String):字符串对。这符合airport变量定义的类型(一个字典只包括字符串(String)键和字符串(String)值),所以在分配字典实量(Dictionary Literals)的时候被允许作为airport字典的两个初始化元素。

和数组一样,如果你初始化一个字典的时候使用相同的类型,你可以不指明字典的类型。
airport初始化可以用下面这个简略写法来代替:

var airports“Dublin”]

因为所有的键在字面上都是相同的类型,同样,所有的值也是同样的类型,所以Swift可以推断为Dictionary<String,String>是airports字典的正确类型。

读取和修改字典
你可以通过属性,方法或者下标来读取和修改字典。和数组一样,你使用只读的count属性来检查字典(Dictionary)包含多少个元素。

"The dictionary of airports contains \(airports.count) items.""The dictionary of airports contains 2 items."

你可以使用下标语法给一个字典添加一个元素。使用合适类型作为新的键,并分配给它一个合适的值

airports["LHR""London"
airports dictionary 现在有 items

你也可以使用下标语法去改变一个特定键所关联的值。

"London Heathrow"
的值已经被改变为 "London Heathrow"

//以上方法和java中就有区别了,java中使用 mMap.put(key,value);向Map对象中插入一条键值对,想要修改的话,只能删掉原来的再新增。

同样,使用字典的updateValue(forKey:) 方法去设置或者更新一个特定键的值 . 和上面的下标例子一样,updateValue(forKey:) 方法如果键不存在则会设置它的值,如果键存在则会更新它的值,和下标不一样是,updateValue(forKey:) 方法 如果更新时,会返回原来旧的值rThis enables you to 可以使用这个来判断是否发生了更新。

5
updateValue forKey 方法返回一个和字典的值相同类型的可选值. 例如,如果字典的值的类型时String,则会返回String? 或者叫“可选String“,这个可选值包含一个如果值发生更新的旧值和如果值不存在的nil值。
let oldValue airports.updateValue "Dublin International" {
"The old value for DUB was \(oldValue)." )
}
"The old value for DUB was Dublin."

你也可以使用下标语法通过特定的键去读取一个值。因为如果他的值不存在的时候,可以返回他的键,字典的下标语法会返回一个字典的值的类型的可选值。如果字典中的键包含对应的值,这字典下标语法会返回这个键所对应的值,否则返回nil

6
let airportName {
"The name of the airport is \(airportName)." )
{
"That airport is not in the airports dictionary." )
}
"The name of the airport is Dublin International."

你可以使用下标语法把他的值分配为nil,来移除这个键值对。

"APL""Apple International"
"Apple International" 不是 APL的真实机场 所以删除它
nil

// APL 已经从字典中被移除
同样,从一个字典中移除一个键值对可以使用removeValueForKey方法,这个方法如果存在键所对应的值,则移除一个键值对,并返回被移除的值,否则返回nil。

let removedValueairports.removeValueForKey{
"The removed airport's name is \(removedValue)." "The airports dictionary does not contain a value for DUB." )
"The removed airport's name is Dublin International."

遍历字典
你可以使用一个for-in循环来遍历字典的键值对。字典中的每一个元素都会返回一个元祖(tuple)/*元组!*/,你可以在循环部分分解这个元祖,并用临时变量或者常量来储存它。

5
airportCode airportName airports "\(airportCode): \(airportName)" TYO Tokyo
LHR London Heathrow

更多有关for-in 循环的信息,参见 For Loops.
你也可以读取字典的keys属性或者values属性来遍历这个字典的键或值的集合。

7
8
9
10
airports.keys "Airport code: \(airportCode)" Airport code TYO
LHR
airports.values {
"Airport name: \(airportName)" )
}
Airport name Tokyo
如果你需要一个接口来创建一个字典的键或者值的数组实例,你可以使用keys或者values属性来初始化一个数值。

let airportCodesairportCodes]
let airportNames airportNames "London Heathrow" ]

注意
Swift中的字典类型是非序列化集合,如果你需要序列化取回键,值,或者键值对,遍历字典不具体叙述。

创建一个空字典
和字典一样,你可以使用确定类型的语法创建一个空的字典。//和数组一样,你可以使用确定类型的语法创建一个空的字典。

var namesOfIntegersIntnamesOfIntegers 是一个空的 Dictionary类型的字典

这个例子创建一个Int,String类型的字典来储存可读性较好的整数值。它的键是Int类型,以及它们的值是String类型。
如果 上下文(context )中已经提供类型信息,可用一个字典实量(Dictionary Literal)创建一个空的字典,写作[;](由一对[]包含一个冒号:)

namesOfIntegers[16"sixteen"
namesOfIntegers现在包含 个键值对
namesOfIntegers ]
namesOfIntegers 是一个类型为Int String的空字典。

注意
在这个场景,Swift数组和字典类型是一个内置的集合。更多的内置类型和集合参见Generics

3、可变集合类型

数组和字典都是在一个集合中一起储存不同的变量.如果你创建一个数组或者字典,再包含一个变量,创建的这个变量被称为可变的(mutable) 这意味这,你可以在创建之后增加更多的元素来改变这个集合的长度,或者移除已经包含的。 相反的,如果你把一个数组或者字典定义为常量,则这个数组或者字典不是可变的,他们的长度并不能被改变。 在字典中,不可变也意味着你不能替换已经存在的键的值。一个不可变字典,一旦被设置就不能改变。 数组的不可变有一点点的不同。然而,你仍然不能做任何有可能修改不可变数组的行为。但是你可以重新设置一个已经存在的索引,这使得当Swift的数组的长度确定时,能更好地优化数组的性能。 拥有可变行为的数组也影响着数组实例的分配和修改,更多内容参见Assignment and Copy Behavior for Collection Types. 注意 在所有的例子中,这是一个好的练习去创建不可变集合,当数组的长度不需要被改变。 我确信Swift编译器能优化好你所创建的集合。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘贴.待开发的功能:1.支持自动生成约束2.开发设置页面3.做一个浏览器插件,支持不需要下载整个工程,可即时操作当前蓝湖浏览页面4.支持Flutter语言模板生成5.支持更多平台,如Sketch等6.支持用户自定义语言模板
现实生活中,我们听到的声音都是时间连续的,我们称为这种信号叫模拟信号。模拟信号需要进行数字化以后才能在计算机中使用。目前我们在计算机上进行音频播放都需要依赖于音频文件。那么音频文件如何生成的呢?音频文件的生成过程是将声音信息采样、量化和编码产生的数字信号的过程,我们人耳所能听到的声音频率范围为(20Hz~20KHz),因此音频文件格式的最大带宽是20KHZ。根据奈奎斯特的理论,音频文件的采样率一般在40~50KHZ之间。奈奎斯特采样定律,又称香农采样定律。...............
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿遍又亿遍,久久不能离开!看着小仙紫姐姐的蹦迪视频,除了一键三连还能做什么?突发奇想,能不能把舞蹈视频转成代码舞呢?说干就干,今天就手把手教大家如何把跳舞视频转成代码舞,跟着仙女姐姐一起蹦起来~视频来源:【紫颜】见过仙女蹦迪吗 【千盏】一、核心功能设计总体来说,我们需要分为以下几步完成:从B站上把小姐姐的视频下载下来对视频进行截取GIF,把截取的GIF通过ASCII Animator进行ASCII字符转换把转换的字符gif根据每
【Android App】实战项目之仿抖音的短视频分享App(附源码和演示视频 超详细必看)
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至2022年4月底。我已经将这篇博客的内容写为论文,上传至arxiv:https://arxiv.org/pdf/2204.10160.pdf欢迎大家指出我论文中的问题,特别是语法与用词问题在github上,我也上传了完整的项目:https://github.com/Whiffe/Custom-ava-dataset_Custom-Spatio-Temporally-Action-Video-Dataset关于自定义ava数据集,也是后台
因为我既对接过session、cookie,也对接过JWT,今年因为工作需要也对接了gtoken的2个版本,对这方面的理解还算深入。尤其是看到官方文档评论区又小伙伴表示看不懂,所以做了这期视频内容出来:视频在这里:本期内容对应B站的开源视频因为涉及的知识点比较多,视频内容比较长。如果你觉得看视频浪费时间,可以直接阅读源码:goframe v2版本集成gtokengoframe v1版本集成gtokengoframe v2版本集成jwtgoframe v2版本session登录官方调用示例文档jwt和sess
【Android App】实战项目之仿微信的私信和群聊App(附源码和演示视频 超详细必看)
用Android Studio的VideoView组件实现简单的本地视频播放器。本文将讲解如何使用Android视频播放器VideoView组件来播放本地视频和网络视频,实现起来还是比较简单的。VideoView组件的作用与ImageView类似,只是ImageView用于显示图片,VideoView用于播放视频。...
采用MATLAB对正弦信号,语音信号进行生成、采样和内插恢复,利用MATLAB工具箱对混杂噪声的音频信号进行滤波
随着移动互联网、云端存储等技术的快速发展,包含丰富信息的音频数据呈现几何级速率增长。这些海量数据在为人工分析带来困难的同时,也为音频认知、创新学习研究提供了数据基础。在本节中,我们通过构建生成模型来生成音频序列文件,从而进一步加深对序列数据处理问题的了解。
基于yolov5+deepsort+slowfast算法的视频实时行为检测。1. yolov5实现目标检测,确定目标坐标 2. deepsort实现目标跟踪,持续标注目标坐标 3. slowfast实现动作识别,并给出置信率 4. 用框持续框住目标,并将动作类别以及置信度显示在框上
数字电子钟设计本文主要完成数字电子钟的以下功能1、计时功能(24小时)2、秒表功能(一个按键实现开始暂停,另一个按键实现清零功能)3、闹钟功能(设置闹钟以及到时响10秒)4、校时功能5、其他功能(清零、加速、星期、八位数码管显示等)前排提示:前面几篇文章介绍过的内容就不详细介绍了,可以看我专栏的前几篇文章。PS.工程文件放在最后面总体设计本次设计主要是在前一篇文章 数字电子钟基本功能的实现 的基础上改编而成的,主要结构不变,分频器将50MHz分为较低的频率备用;dig_select
1.进入官网下载OBS stdioOpen Broadcaster Software | OBS (obsproject.com)2.下载一个插件,拓展OBS的虚拟摄像头功能链接:OBS 虚拟摄像头插件.zip_免费高速下载|百度网盘-分享无限制 (baidu.com)提取码:6656--来自百度网盘超级会员V1的分享**注意**该插件必须下载但OBS的根目录(应该是自动匹配了的)3.打开OBS,选中虚拟摄像头选择启用在底部添加一段视频录制选择下面,进行录制.
Meta公司在9月29日首次推出一款人工智能系统模型:Make-A-Video,可以从给定的文字提示生成短视频。基于**文本到图像生成技术的最新进展**,该技术旨在实现文本到视频的生成,可以仅用几个单词或几行文本生成异想天开、独一无二的视频,将无限的想象力带入生活
音频信号叠加噪声及滤波一、前言二、信号分析及加噪三、滤波去噪四、总结一、前言之前一直对硬件上的内容比较关注,但是可能是因为硬件方面的东西可能真的是比较杂,而且需要渗透的东西太多了,所以学习进展比较缓慢。因为也很少有单纯的硬件学习研究,总是会伴随着各种理论需要硬件做支撑,所以还是想要慢慢接触理论学习。但是之前总找不到切入点,不知道从哪里开始,就一直拖着。最近稍微接触了一点信号处理,就用这个当作切入点,开始接触理论学习。二、信号分析及加噪信号处理选用了matlab做工具,选了一个最简单的语音信号处理方
腾讯云 TRTC 实时音视频服务体验,从认识 TRTC 到 TRTC 的开发实践,Demo 演示& IM 服务搭建。
音乐音频分类技术能够基于音乐内容为音乐添加类别标签,在音乐资源的高效组织、检索和推荐等相关方面的研究和应用具有重要意义。传统的音乐分类方法大量使用了人工设计的声学特征,特征的设计需要音乐领域的知识,不同分类任务的特征往往并不通用。深度学习的出现给更好地解决音乐分类问题提供了新的思路,本文对基于深度学习的音乐音频分类方法进行了研究。首先将音乐的音频信号转换成声谱作为统一表示,避免了手工选取特征存在的问题,然后基于一维卷积构建了一种音乐分类模型。
C++知识精讲16 | 井字棋游戏(配资源+视频)【赋源码,双人对战】
本文主要讲解如何在Java中,使用FFmpeg进行视频的帧读取,并最终合并成Gif动态图。
在本篇博文中,我们谈及了 Swift 中 some、any 关键字以及主关联类型(primary associated types)的前世今生,并由浅及深用简明的示例向大家讲解了它们之间的奥秘玄机。