集合类型

Swift提供了三种集合类型,数组、set和字典,用来存放一系列内容。数组顺序存放统一类型的值。set是互不相同值的无序集合。字典也是键值对的无序集合。

Swift中数组、set和字典的键和值的类型是明确的。这就意味着你不能将一个不符合的类型值塞入到集合类型中。也意味着从集合中取到的类型一定是确定的。

Note

Swift的数组、set和字典是作为泛型集合的实现的。更多的关于泛型类型和集合的内容,参见 泛型 一章。

集合的易变性

如果你创建了一个集合,并且将其赋值给了一个变量,这个集合就具有了易变性。意思就是在这个集合被创建后,它可以被添加内容、移除内容、或者改变内容。相反,如果你将这个集合赋值给了一个常量,它就不能被修改了,他的长度和内容都不能被修改。
不能被修改的集合最好声明为常量,这样Swfit编译器会对其优化处理。

数组

数组可以接受多个同一类型的值,同一值可以出现在多个不同的位置。
Swfit的数组和OC中的不同点在于其可以存放的值类型,OC中的NSArray 和NSMutableArray 能够接受任何类型的值而且在访问其中内容时没有任何有关类型的提示。Swift的数组存放类型是明确的,类型声明可以是一个明确的类型或者接口或者特定类。如果你创建了一个Int类型的数组,你就不能向其添加任何非Int的数据。Swift的数组是类型安全的,你能明确的知道其中存放的内容类型。

数组类型的简短语法

完整版:Array 或者简化版:[SomeType]。尽管二者功能效果一样,但简化版本是首选,本文将在涉及这方面的情形都采用简化版本。

数组字面值

你可以在用array声明一个数组后,给它赋值,赋值的格式如下:
[value 1,value 2,value 3]
下面的例子创建了一个叫shoppingList 的数组,里面存储字符串:
​var​ ​shoppingList​: [​String​] = [​”Eggs”​,​”Milk”​]
​// shoppingList has been initialized with two initial items
这个例子中字面值包括了两个字符串没有其它类型,和数组的类型声明一致,所以赋值语句被允许进行,两个字符串作为初始化的参数给了初始化方法。
凭借Swift的类型接口,如果你的初始化数据里面是相同的类型,你可以省去数组的类型定义:
​var​ ​shoppingList​ = [​”Eggs”​,​”Milk”​]
因为所有的值都是同一类型,所以Swift可以推断出变量shoppingList正确的数组类型。

访问和修改数组

你可以通过数组的方法和属性对其进行访问和修改,当然也可以通过下标。
通过只读属性count 获得数组内容的个数:

​println​(​"The shopping list contains ​\(​shoppingList​.​count​)​ items."​)
​// prints "The shopping list contains 2 items."

通过布尔类型的属性isEmpty 判断数组是否有内容,这是判断count 等于0的一个简化方式:

if​ ​shoppingList​.​isEmpty​ {
​ ​println​(​"The shopping list is empty."​)
​} ​else​ {
​ ​println​(​"The shopping list is not empty."​)
​}
​// prints "The shopping list is not empty."

通过append 给数组添加内容

​shoppingList​.​append​(​"Flour"​)
​// shoppingList Now contains 3 items,and someone is making pancakes

或者通过+=给数组添加一个或多个的内容:

​shoppingList​ += [​"Baking Powder"​]
​// shoppingList Now contains 4 items
​shoppingList​ += [​"Chocolate Spread"​,​"Cheese"​,​"Butter"​]
​// shoppingList Now contains 7 items

通过下标访问数组内容:

var​ ​firstItem​ = ​shoppingList​[​0​]
​// firstItem is equal to "Eggs"

Swift的数组下标从0开始。
你也可以通过下标修改数组内容:

​shoppingList​[​0​] = ​"Six eggs"
​// the first item in the list is Now equal to "Six eggs" rather than "Eggs"

你可以使用下标一次替换数组内一定范围的内容,如果你要修改的范围和你提供的修改值个数不符也没有关系。

​shoppingList​[​4​...​6​] = [​"Bananas"​,​"Apples"​]
​// shoppingList Now contains 6 items

疑问:用下标的范围表示法?是采用0开始还是1?上例中操作前数组长度为6吧?
你不能通过下标向一个数组照插入内容。通过下标访问和修改内容时,如果下表超出范围,会有一个运行时错误。你可以通过检查数组长度(通过count 属性)来避免上述情况。除非count为0的情况,数组的长度都是count-1.

向一个数组中插入内容,采用insert(atIndex:)方法:

shoppingList​.​insert​(​"Maple Syrup"​,​atIndex​: ​0​)
​// shoppingList Now contains 7 items
​// "Maple Syrup" is Now the first item in the list
将"Maple Syrup"添加到数组的第一个位置

删除数组中特定内容采用removeAtIndex ,这个方法还会返回删除的内容,当然你可以完全忽略这个返回值。

let​ ​mapleSyrup​ = ​shoppingList​.​removeAtIndex​(​0​)
​// the item that was at index 0 has just been removed
​// shoppingList Now contains 6 items,and no Maple Syrup
​// the mapleSyrup constant is Now equal to the removed "Maple Syrup" string

删除操作后,数组中出现了间隙,后续的内容会向前填充。这时的第一个元素已经是:”Six eggs”

​firstItem​ = ​shoppingList​[​0​]
​// firstItem is Now equal to "Six eggs"

如果你要删除数组的最后一个元素,那么可以采用removeLast ,这样就可以避免使用removeAtIndex 删除时还得调用count 。和removeAtIndex 一样,removeLast 范围你删除的内容。

​let​ ​apples​ = ​shoppingList​.​removeLast​()
​// the last item in the array has just been removed
​// shoppingList Now contains 5 items,and no apples
​// the apples constant is Now equal to the removed "Apples" string

遍历数组

可以采用for-in遍历数组

​for​ ​item​ ​in​ ​shoppingList​ {
​ ​println​(​item​)
​}
​// Six eggs
​// Milk
​// Flour
​// Baking Powder
​// Bananas

如果你需要根据数组的索引做些事情,此时可以使用全局方法enumerate遍历数组。enumerate 返回数组对应的元组,其中包括了内容的索引和内容值。处理元组就可以解析数组内容了。

for​ (​index​,​value​) ​in​ ​enumerate​(​shoppingList​) {
​ ​println​(​"Item ​\(​index​ + ​1​)​: ​\(​value​)​"​)
​}
​// Item 1: Six eggs
​// Item 2: Milk
​// Item 3: Flour
​// Item 4: Baking Powder
​// Item 5: Bananas

具体可以查看循环 for-in语法。

创建和初始化数组(本节已经删除)

你可以创建一个特定类型的空数组:

​var​ ​someInts​ = [​Int​]()
​println​(​"someInts is of type [Int] with ​\(​someInts​.​count​)​ items."​)
​// prints "someInts is of type [Int] with 0 items."

这样写,someInts只接受Int类型的数据。

在给定了数组的类型后,可以使用“[]”初始化或者复制

​someInts​.​append​(​3​)
​// someInts Now contains 1 value of type Int
​someInts​ = []
​// someInts is Now an empty array,but is still of type [Int]

Swift的数组初始化方法提供了设置数组长度和缺省值的功能。数组长度对应的参数叫:count,缺省值对应的参数叫:repeatedValue

​var​ ​threeDoubles​ = [​Double​](​count​: ​3​,​repeatedValue​: ​0.0​)
​// threeDoubles is of type [Double],and equals [0.0,0.0,0.0]

创建了一个类型为Double,长度为3,缺省值为0.0的数组。

你可以用+将两个数组组合在一起,创建出了一个类型相同的数组:

​var​ ​anotherThreeDoubles​ = [​Double​](​count​: ​3​,​repeatedValue​: ​2.5​)
​// anotherThreeDoubles is inferred as [Double],and equals [2.5,2.5,2.5]
​
​var​ ​sixDoubles​ = ​threeDoubles​ + ​anotherThreeDoubles
​// sixDoubles is inferred as [Double],2.5]

Sets

一个Set存储相同类型的不同值,而且不排序。可以在不关心排序的情形使用Set替代数组。在需要限制一个元素在集合中只能出现一次时,使用Set。

NOTE
Swift的Set类型是与系统底层NSSet类的桥梁。更多的关于使用Set操控底层和Cocoa的信息,参见 用Swift操控Cocoa和Objective-C。

字典

字典是个存放同一类型内容的容器,在字典中每个内容都有唯一对应的键与其对应。和数组不同,字典中的内容没有特定的顺序而言。和现实中的字典一样,你可以通过键查找字典中的内容。
Swift的字典明确了键和值的类型。这和OC中的NSDictionary 、NSMutableDictionary 不同。

字典类型的简写

Dictionary

字典的字面值

你可以像数组那样给出字典的字面值用于初始化。字面值是若干键-值对构成的。
[key 1: value 1,key 2: value 2,key 3: value 3]
下面这个例子中,字典的键是三个字母构成的航空协会编码,对应的值是机场的名字:
​var​ ​airports​: [​String​: ​String​] = [​”YYZ”​: ​”Toronto Pearson”​,​”dub”​: ​”dublin”​]
这个名字为airports的字典是一个[String:String]类型,意思就是一个键是String类型、值是String类型的字典。
这个字典被定义为变量,因为我们后面需要修改它。
和数组类似,省去类型后,简写的方式为:
var​ ​airports​ = [​”YYZ”​: ​”Toronto Pearson”​,​”dub”​: ​”dublin”​]
因为赋值的内容 类型都一样,所以Swift编译器可以推断出他们的正确类型。

访问和修改字典

访问和修改字典可以通过它的属性和方法,或者通过下标。和数组一样,count这个只读属性可以告诉你字典的长度。

​println​(​"The airports dictionary contains ​\(​airports​.​count​)​ items."​)
​// prints "The airports dictionary contains 2 items."

isEmpty 属性判断一个字典是否长度是0

​if​ ​airports​.​isEmpty​ {
​ ​println​(​"The airports dictionary is empty."​)
​} ​else​ {
​ ​println​(​"The airports dictionary is not empty."​)
​}
​// prints "The airports dictionary is not empty."

可以采用下标添加一个内容到一个字典,使用一个从未使用的键做下标,然后赋值给它(键值的类型都要对):

airports​[​"LHR"​] = ​"London"
​// the airports dictionary Now contains 3 items

也可以通过下标修改字典的一个内容:

​airports​[​"LHR"​] = ​"London Heathrow"
​// the value for "LHR" has been changed to "London Heathrow"

另外的一种方式通过updateValue(forKey:)方法,设置或修改指定键的内容。和下标方式一样,这个方式在没有对应的值的时候创建一个值给对应的键,在有对应值的时候修改那个值。和下标方式不同的地方是,这个方法在修改了值的时候,会返回原来的值。这个功能让你能够检查更新有没有生效。

updateValue(forKey:)返回的是一个字典值类型的可选类型。如果做了修改操作,将返回修改前的值;否则将返回nil;

​if​ ​let​ ​oldValue​ = ​airports​.​updateValue​(​"dublin Airport"​,​forKey​: ​"dub"​) {
​ ​println​(​"The old value for dub was ​\(​oldValue​)​."​)
​}
​// prints "The old value for dub was dublin."

同理,用下标访问字典的内容,返回的也是一个字典值类型的可选类型。有值返回值,没有值返回nil。

​if​ ​let​ ​airportName​ = ​airports​[​"dub"​] {
​ ​println​(​"The name of the airport is ​\(​airportName​)​."​)
​} ​else​ {
​ ​println​(​"That airport is not in the airports dictionary."​)
​}
​// prints "The name of the airport is dublin Airport."

通过下标方式,用nil赋值,可以删除字典中的一个键值对

airports​[​"APL"​] = ​"Apple International"
​// "Apple International" is not the real airport for APL,so delete it
​airports​[​"APL"​] = ​nil
​// APL has Now been removed from the dictionary

removeValueForKey 是另外一种删除字典键值对的方式,这个方法在返回删除掉的值或者nil。

if​ ​let​ ​removedValue​ = ​airports​.​removeValueForKey​(​"dub"​) {
​ ​println​(​"The removed airport's name is ​\(​removedValue​)​."​)
​} ​else​ {
​ ​println​(​"The airports dictionary does not contain a value for dub."​)
​}
​// prints "The removed airport's name is dublin Airport."

遍历字典

你可以通过for-in语句遍历一个字典,每个字典有对应有一个由键值对构成的元组,处理这个元组即可。

for​ (​airportCode​,​airportName​) ​in​ ​airports​ {
​ ​println​(​"​\(​airportCode​)​: ​\(​airportName​)​"​)
​}
​// LHR: London Heathrow
​// YYZ: Toronto Pearson

当然你可以通过遍历键或者值的方式遍历整个字典:

​for​ ​airportCode​ ​in​ ​airports​.​keys​ {
​ ​println​(​"Airport code: ​\(​airportCode​)​"​)
​}
​// Airport code: LHR
​// Airport code: YYZ
​
​for​ ​airportName​ ​in​ ​airports​.​values​ {
​ ​println​(​"Airport name: ​\(​airportName​)​"​)
​}
​// Airport name: London Heathrow
​// Airport name: Toronto Pearson

如果你想将字典的键或者值分别存放到数组中,创建两个数组就行了:

let​ ​airportCodes​ = [​String​](​airports​.​keys​)
​// airportCodes is ["LHR","YYZ"]
​
​let​ ​airportNames​ = [​String​](​airports​.​values​)
​// airportNames is ["London Heathrow","Toronto Pearson"]

字典是无序的容器,The order in which keys,values,and key-value pairs are retrieved when iterating over a dictionary is not specified.

创建一个空的字典

var​ ​namesOfIntegers​ = [​Int​: ​String​]()
​// namesOfIntegers is an empty [Int: String] dictionary

如果字典的类型确定了,可以用[:]将字典重新置为空:

​namesOfIntegers​[​16​] = ​"sixteen"
    ​// namesOfIntegers Now contains 1 key-value pair
    ​namesOfIntegers​ = [:]
    ​// namesOfIntegers is once again an empty dictionary of type [Int: String]

字典键类型要有哈希值

字典键的类型需要提供比较哈西值的方法。哈西值是一个Int的数字,用来比较两个对象是否相等的。这么说吧,如果两个对象相等,那么他们的哈希值相等。
所有Swfit的基本类型都有默认的哈希值,自然可以作为字典的键。没有关联值(在枚举中有描述)的枚举成员值默认都是hashable的。

NOTE

可以用自定义的类型做字典的键,前提是你的类遵循Swift的标准库中的Hashable 协议。具体做法是需要有个一叫做hashValue的Int类型的可读属性(getter),还要给出“相等”操作符(==)的实现。一个类型的hasValue属性返回值不需要经过相同程序的执行得到一样的结果,同样不需要经过不同的程序执行得到一样的结果。

[翻译]Swift编程语言——集合类型的更多相关文章

  1. html5使用canvas实现弹幕功能示例

    这篇文章主要介绍了html5使用canvas实现弹幕功能示例的相关资料,需要的朋友可以参考下

  2. HTML5 WebSocket实现点对点聊天的示例代码

    这篇文章主要介绍了HTML5 WebSocket实现点对点聊天的示例代码的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  3. 前端实现弹幕效果的方法总结(包含css3和canvas的实现方式)

    这篇文章主要介绍了前端实现弹幕效果的方法总结(包含css3和canvas的实现方式)的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  4. H5 canvas实现贪吃蛇小游戏

    本篇文章主要介绍了H5 canvas实现贪吃蛇小游戏,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

  6. ios – 声明NSDictionary并在Swift中添加键值对?

    我一直在尝试使用类类型键和值来声明一个NSDictionary,如下所示:这里,“Category”和“SubCategory”是全局类.我知道我不能将类类型用于关键字段.但是,无论如何,我应该做到这一点.有没有办法做到这一点?如何声明专门的NSDictionary或类似的东西来做到这一点?

  7. ios – parse.com用于键,预期字符串的无效类型,但是得到了数组

    我尝试将我的数据保存到parse.com.我已经预先在parse.com上创建了一个名为’SomeClass’的类.它有一个名为’mySpecialColumn’的列,其数据类型为String.这是我尝试使用以下代码保存数据的代码:如果我运行这个我得到:错误:密钥mySpecialColumn的无效类型,预期字符串,但得到数组这就是我在parse.com上的核心外观:有谁知道我为什么会收到这个错误?

  8. ios – 在Swift中将输入字段字符串转换为Int

    所以我非常擅长制作APP广告Swift,我试图在文本字段中做一些非常简单的输入,取值,然后将它们用作Int进行某些计算.但是’vardistance’有些东西不正确它是导致错误的最后一行代码.它说致命错误:无法解开Optional.None解决方法在你的例子中,距离是一个Int?否则称为可选的Int..toInt()返回Int?因为从String到Int的转换可能失败.请参阅以下示例:

  9. ios – Swift相当于`[NSDictionary initWithObjects:forKeys:]`

    Swift的原生字典是否与[NSDictionaryinitWithObjects:forKeys:]相当?假设我有两个带键和值的数组,并希望将它们放在字典中.在Objective-C中,我这样做:当然我可以通过两个数组迭代一个计数器,使用vardict:[String:Int]并逐步添加东西.但这似乎不是一个好的解决方案.使用zip和enumerate可能是同时迭代两者的更好方法.然而,这种方法

  10. 如何在iOS中检测文本(字符串)语言?

    例如,给定以下字符串:我想检测每个声明的字符串中使用的语言.让我们假设已实现函数的签名是:如果没有检测到语言,则返回可选字符串.因此,适当的结果将是:有一个简单的方法来实现它吗?

随机推荐

  1. Swift UITextField,UITextView,UISegmentedControl,UISwitch

    下面我们通过一个demo来简单的实现下这些控件的功能.首先,我们拖将这几个控件拖到storyboard,并关联上相应的属性和动作.如图:关联上属性和动作后,看看实现的代码:

  2. swift UISlider,UIStepper

    我们用两个label来显示slider和stepper的值.再用张图片来显示改变stepper值的效果.首先,这三个控件需要全局变量声明如下然后,我们对所有的控件做个简单的布局:最后,当slider的值改变时,我们用一个label来显示值的变化,同样,用另一个label来显示stepper值的变化,并改变图片的大小:实现效果如下:

  3. preferredFontForTextStyle字体设置之更改

    即:

  4. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 字典实战和UIKit初探

    ios中数组和字典的应用Applicationschedule类别子项类别名称优先级数据包contactsentertainment接触UIKit学习用Swift调用CocoaTouchimportUIKitletcolors=[]varbackView=UIView(frame:CGRectMake(0.0,0.0,320.0,CGFloat(colors.count*50)))backView

  6. swift语言IOS8开发战记21 Core Data2

    上一话中我们简单地介绍了一些coredata的基本知识,这一话我们通过编程来实现coredata的使用。还记得我们在coredata中定义的那个Model么,上面这段代码会加载这个Model。定义完方法之后,我们对coredata的准备都已经完成了。最后强调一点,coredata并不是数据库,它只是一个框架,协助我们进行数据库操作,它并不关心我们把数据存到哪里。

  7. swift语言IOS8开发战记22 Core Data3

    上一话我们定义了与coredata有关的变量和方法,做足了准备工作,这一话我们来试试能不能成功。首先打开上一话中生成的Info类,在其中引用头文件的地方添加一个@objc,不然后面会报错,我也不知道为什么。

  8. swift实战小程序1天气预报

    在有一定swift基础的情况下,让我们来做一些小程序练练手,今天来试试做一个简单地天气预报。然后在btnpressed方法中依旧增加loadWeather方法.在loadWeather方法中加上信息的显示语句:运行一下看看效果,如图:虽然显示出来了,但是我们的text是可编辑状态的,在storyboard中勾选Editable,再次运行:大功告成,而且现在每次单击按钮,就会重新请求天气情况,大家也来试试吧。

  9. 【iOS学习01】swift ? and !  的学习

    如果不初始化就会报错。

  10. swift语言IOS8开发战记23 Core Data4

    接着我们需要把我们的Rest类变成一个被coredata管理的类,点开Rest类,作如下修改:关键字@NSManaged的作用是与实体中对应的属性通信,BinaryData对应的类型是NSData,CoreData没有布尔属性,只能用0和1来区分。进行如下操作,输入类名:建立好之后因为我们之前写的代码有些地方并不适用于coredata,所以编译器会报错,现在来一一解决。

返回
顶部