Swift学习笔记 - 教程学习三 集合类型 (Collection Types)

集合类型 (Collection Types)

本节及前面用到的for…in句型在后面的循环控制部分,if let 见基础篇。如果某些字符看不到,请到博客园来看原文。——新波

Swift提供了三种基本集合类型,数组(array)、集合(set)和字典(dictionary)。数组是一组按序排列的数据,集合是一组各不相同的无序数据,字典是一组与关键值相关联的无序数据。参见下图。

 

3.1 集合的可变性Mutability of Collections

与前面的字符串一样,赋值给变量的集合是可变的,赋值给常量的是不可变的。如果创建一个ArraySetDictionary并且把它分配成一个变量,它就是可变的。也就是说可以替换、增减其中的元素。如果把创建的ArraySetDictionary分配给常量,那么它就是不可变的,其元素不能替换和增减。

3.2 数组Arrays

数组用于存储有序排列多个同类型的值。相同的值可以多次出现。

数组的简单语法Array Type Shorthand Syntax

Array<Element>Element是这个数组中唯一允许存在的数据类型。

[Element] 简写,推荐形式。

创建一个空数组Creating an Empty Array

var someInts = [Int]()

print("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]

创建一个带有默认值的数组Creating an Array with a Default Value

var threeDoubles = [Double](count: 3, repeatedValue: 0.0)

// threeDoubles is of type [Double], and equals [0.0, 0.0, 0.0]

两数组相加创建数组Creating an Array by Adding Two Arrays Together

var anotherThreeDoubles = [Double](count: 3, repeatedValue: 2.5)

// anotherThreeDoubles is of type [Double], and equals [2.5, 2.5, 2.5]

var sixDoubles = threeDoubles + anotherThreeDoubles

// sixDoubles is inferred as [Double], and equals [0.0, 0.0, 0.0, 2.5, 2.5, 2.5]

用字面量构造数组Creating an Array with an Array Literal

[value 1, value 2, value 3]

var shoppingList: [String] = ["Eggs", "Milk"]

// shoppingList has been initialized with two initial items

访问和修改数组Accessing and Modifying an Array

可以通过属性、方法和下标访问、修改数组。

只读属性count反映数组包含的元素数量。isEmpty是否为空

print("The shopping list contains \(shoppingList.count) items.")

// Prints "The shopping list contains 2 items."

if shoppingList.isEmpty {

print("The shopping list is empty.")

} else {

print("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"

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

插入insert(_:at:)删除removeAtIndex(0)

shoppingList.insert("Maple Syrup", atIndex: 0)

// shoppingList now contains 7 items

// "Maple Syrup" is now the first item in the list

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

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

数组的遍历Iterating Over an Array

for item in shoppingList {

print(item)

}

// Six eggs // Milk // Flour // Baking Powder // Bananas

for (index, value) in shoppingList.enumerate() {

print("Item \(index + 1): \(value)")

}

// Item 1: Six eggs // Item 2: Milk // Item 3: Flour // Item 4: Baking Powder // Item 5: Bananas

3.3 集合Sets

Set用来存储相同类型并且没有确定顺序的值。当集合元素顺序不重要时或者希望确保每个元素只出现一次时,使用集合而不是数组。

集合类型的哈希值Hash Values for Set Types

哈希算法将任意长度的二进制值映射为固定长度的较小二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。一个类型为了存储在集合中,该类型必须是可哈希化的--也就是说,该类型必须提供一个方法来计算它的哈希值。哈希值是Int类型的,并且相等对象的哈希值必须相等,比如a==b,因此必有a.hashValue ==b.hashValueSwift 的所有基本类型(String , Int , Double Bool )默认都是可哈希化的,可以作为集合的值的类型或者字典的键的类型。

因为 Hashable 协议符合 Equatable 协议,所以符合该协议的类型也必须提供一个"是否相等"运算符( == )的实现。这个Equatable 协议要求任何符合==实现的实例间都是一种相等的关系。也就是说,对于a, b, c三个值来说,==的实现必须满足下面三种情况:

a == a (自反性)

a == b 意味着 b == a (对称性)

a == b && b == c 意味着 a == c (传递性)

集合类型语法Set Type Syntax

Set<Element>,这里的Element表示Set中允许存储的类型。

创建和构造一个空的集合Creating and Initializing an Empty Set

var letters = Set<Character>()

print("letters is of type Set<Character> with \(letters.count) items.")

// Prints "letters is of type Set<Character> with 0 items."

letters.insert("a")

// letters now contains 1 value of type Character

letters = []

// letters is now an empty set, but is still of type Set<Character>

用数组字面量创建集合Creating a Set with an Array Literal

var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]

// favoriteGenres has been initialized with three initial items

favoriteGenres 的构造形式可以采用简化的方式:

var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"]

访问和修改集合Accessing and Modifying a Set

通过属性和方法访问修改setcount集合中元素数量,isEmpty是否为空。

print("I have \(favoriteGenres.count) favorite music genres.")

// "I have 3 favorite music genres."

if favoriteGenres.isEmpty {

print("As far as music goes, I'm not picky.")

} else {

print("I have particular music preferences.")

}

//  "I have particular music preferences."

插入元素insert

favoriteGenres.insert("Jazz")

// favoriteGenres 现在包含4个元素

if let removedGenre = favoriteGenres.remove("Rock") {

print("\(removedGenre)? I'm over it.")

} else {

print("I never much cared for that.")

}

// "Rock? I'm over it."

使用 contains(_:) 方法去检查 Set 中是否包含一个特定的值:

if favoriteGenres.contains("Funk") {

print("I get up on the good foot.")

} else {

print("It's too funky in here.")

}

// 打印 "It's too funky in here."

遍历一个集合Iterating Over a Set

for genre in favoriteGenres {

print("\(genre)")

}

// Classical  // Jazz  // Hip hop

使用 sort() 方法根据提供的序列返回一个有序集合.

for genre in favoriteGenres.sort() {

print("\(genre)")

}

// prints "Classical"  // prints "Hip hop"  // prints "Jazz

集合操作Performing Set Operations

判断两个集合是否共有元素,是否全包含、部分包含或者不相交。

基本集合操作Fundamental Set Operations

intersect(_:)方法创建一个只包含两个集合共有元素的新集合

exclusiveOr(_:)方法创建一个包含只在其中一个而非共有的元素的新集合(values in either set, but not both

union(_:)方法创建一个包含两个集合中全部元素的新集合

subtract(_:)方法创建一个不包含指定集合中元素的新集合(values not in the specified set.

 

let oddDigits: Set = [1, 3, 5, 7, 9]

let evenDigits: Set = [0, 2, 4, 6, 8]

let singleDigitPrimeNumbers: Set = [2, 3, 5, 7]

oddDigits.union(evenDigits).sort()

// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

oddDigits.intersect(evenDigits).sort()

// []

oddDigits.subtract(singleDigitPrimeNumbers).sort()

// [1, 9]

oddDigits.exclusiveOr(singleDigitPrimeNumbers).sort()

// [1, 2, 9]

集合成员关系和相等Set Membership and Equality

使用“是否相等”运算符( == )来判断两个集合是否包含全部相同的元素。

使用isSubsetOf(_:) 方法来判断一个集合中的元素是否也被包含在另外一个集合中。

使用isSupersetOf(_:) 方法来判断一个集合中包含另一个集合中所有的元素。

使用isStrictSubsetOf(_:)或者isStrictSupersetOf(_:)方法来判断一个集合是否是另外一个集合的子集合或者父集合并且两个集合并不相等。

使用 isDisjointWith(_:) 方法来判断两个集合是否不含有相同的值。

 

lethouseAnimals:  Set = ["🐶", "🐱"]//猫、狗

letfarmAnimals:  Set = ["🐮", "🐔", "🐑", "🐶", "🐱"]//

letcityAnimals: Set = ["🐦", "🐭"]

houseAnimals.isSubsetOf(farmAnimals)

// true

farmAnimals.isSupersetOf(houseAnimals)

// true

farmAnimals.isDisjointWith(cityAnimals)

// true

3.4 字典Dictionaries

字典是一种存储多个同类型值的容器。每个值(value)都关联唯一的键(key),键作为字典中这个值的标识符。

字典类型快捷语法Dictionary Type Shorthand Syntax

Dictionary<Key, Value> or [Key: Value],其中Key是字典中键的数据类型,Value是字典中对应于这些键所存储值的数据类型。Key类型必须遵循Hashable协议,就像Set的值类型。

创建一个空字典Creating an Empty Dictionary

var namesOfIntegers = [Int: String]()

// namesOfIntegers 是一个空的 [Int: String] 字典

namesOfIntegers[16] = "sixteen"

// namesOfIntegers 现在包含一个键值对

namesOfIntegers = [:]

// namesOfIntegers 又成为了一个 [Int: String] 类型的空字典

用字典字面量创建字典Creating a Dictionary with a Dictionary Literal

 [key 1: value 1, key 2: value 2, key 3: value 3]

var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]

可以var airports = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]

访问和修改字典Accessing and Modifying a Dictionary

可以通过方法、属性和下标访问修改字典。count元素数量。isEmpty是否为空

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

// "The dictionary of airports contains 2 items."(这个字典有两个数据项)

if airports.isEmpty {

print("The airports dictionary is empty.")

} else {

print("The airports dictionary is not empty.")

}

//  "The airports dictionary is not empty."

通过下标键值添加、修改

airports["LHR"] = "London"

// airports 字典现在有三个数据项

airports["LHR"] = "London Heathrow"

// "LHR"对应的值被改为 "London Heathrow

updateValue(_:forKey:)

if let oldValue = airports.updateValue("Dublin Airport", forKey: "DUB") {

print("The old value for DUB was \(oldValue).")

}

// 输出 "The old value for DUB was Dublin."

如果有值存在于更新前,则这个可选值包含了旧值,否则它将会是nil

if let airportName = airports["DUB"] {

print("The name of the airport is \(airportName).")

} else {

print("That airport is not in the airports dictionary.")

}

// 打印 "The name of the airport is Dublin Airport."

airports["APL"] = "Apple Internation"

// "Apple Internation" 不是真的 APL 机场, 删除它

airports["APL"] = nil

// APL 现在被移除了

 removeValueForKey(_:) 方法也可以用来在字典中移除键值对。这个方法在键值对存在的情况下会移除该键值对并且返回被移除的值,在没有值的情况下返回nil

if let removedValue = airports.removeValueForKey("DUB") {

print("The removed airport's name is \(removedValue).")

} else {

print("The airports dictionary does not contain a value for DUB.")

}

// prints "The removed airport's name is Dublin Airport."

字典遍历Iterating Over a Dictionary

for (airportCode, airportName) in airports {

print("\(airportCode): \(airportName)")

}

// YYZ: Toronto Pearson

// LHR: London Heathrow

for airportCode in airports.keys {

print("Airport code: \(airportCode)")

}

// Airport code: YYZ

// Airport code: LHR

for airportName in airports.values {

print("Airport name: \(airportName)")

}

// Airport name: Toronto Pearson

// Airport name: London Heathrow

 

let airportCodes = [String](airports.keys)

// airportCodes ["YYZ", "LHR"]

let airportNames = [String](airports.values)

// airportNames ["Toronto Pearson", "London Heathrow"]

posted @ 2016-06-28 10:22  新波  阅读(257)  评论(0编辑  收藏  举报