[翻译]Swift编程语言——集合类型
集合类型Swift提供了三种集合类型,数组、set和字典,用来存放一系列内容。数组顺序存放统一类型的值。set是互不相同值的无序集合。字典也是键值对的无序集合。 Swift中数组、set和字典的键和值的类型是明确的。这就意味着你不能将一个不符合的类型值塞入到集合类型中。也意味着从集合中取到的类型一定是确定的。 Note Swift的数组、set和字典是作为泛型集合的实现的。更多的关于泛型类型和集合的内容,参见 泛型 一章。 集合的易变性如果你创建了一个集合,并且将其赋值给了一个变量,这个集合就具有了易变性。意思就是在这个集合被创建后,它可以被添加内容、移除内容、或者改变内容。相反,如果你将这个集合赋值给了一个常量,它就不能被修改了,他的长度和内容都不能被修改。 数组数组可以接受多个同一类型的值,同一值可以出现在多个不同的位置。 数组类型的简短语法完整版:Array 或者简化版:[SomeType]。尽管二者功能效果一样,但简化版本是首选,本文将在涉及这方面的情形都采用简化版本。 数组字面值你可以在用array声明一个数组后,给它赋值,赋值的格式如下: 访问和修改数组你可以通过数组的方法和属性对其进行访问和修改,当然也可以通过下标。 ?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吧? 向一个数组中插入内容,采用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 字典字典是个存放同一类型内容的容器,在字典中每个内容都有唯一对应的键与其对应。和数组不同,字典中的内容没有特定的顺序而言。和现实中的字典一样,你可以通过键查找字典中的内容。 字典类型的简写Dictionary 字典的字面值你可以像数组那样给出字典的字面值用于初始化。字面值是若干键-值对构成的。 访问和修改字典访问和修改字典可以通过它的属性和方法,或者通过下标。和数组一样,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的数字,用来比较两个对象是否相等的。这么说吧,如果两个对象相等,那么他们的哈希值相等。 NOTE 可以用自定义的类型做字典的键,前提是你的类遵循Swift的标准库中的Hashable 协议。具体做法是需要有个一叫做hashValue的Int类型的可读属性(getter),还要给出“相等”操作符(==)的实现。一个类型的hasValue属性返回值不需要经过相同程序的执行得到一样的结果,同样不需要经过不同的程序执行得到一样的结果。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |