➽03集合类型
Posted itzyjr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了➽03集合类型相关的知识,希望对你有一定的参考价值。
Swift提供了三种主要的集合类型,即Array、Set和Dictionary,用于存储值集合。Arrays是值的有序集合。Sets是唯一值的无序集合。Dictionarys是键值关联的无序集合。
Swift的Array、Set和Dictionary类型实现为泛型集合。
在不需要更改集合的所有情况下,创建不可变集合都是一种很好的做法。这样做可以使您更容易对代码进行推理,并使Swift编译器能够优化您创建的集合的性能。
Arrays
数组在有序列表中存储相同类型的值。相同的值可以在数组中的不同位置多次出现。
Swift数组的类型完整地写为Array<Element>,其中Element是允许数组存储的值的类型。您还可以将数组的类型以简写形式写为[Element]。尽管这两种形式在功能上是相同的,但速记形式是首选形式,在本指南中提及数组类型时使用速记形式。
创建一个空Array
var someInts: [Int] = []
print("someInts is of type [Int] with \\(someInts.count) items.")
// Prints "someInts is of type [Int] with 0 items."
someInts.append(3)
// someInts now contains 1 value of type Int
someInts = []
// someInts is now an empty array, but is still of type [Int]
创建带默认值的Array
向该初始值设定项传递适当类型的默认值(称为repeating
)以及该值在新数组中重复的次数(称为count
):
var threeDoubles = Array(repeating: 0.0, count: 3)
// threeDoubles is of type [Double], and equals [0.0, 0.0, 0.0]
创建数组:两Array相加
var anotherThreeDoubles = Array(repeating: 2.5, count: 3)
// 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]
用数组字面量创建Array
var shoppingList: [String] = ["Eggs", "Milk"]
// shoppingList has been initialized with two initial items
shoppingList变量声明为“字符串值数组”,写为[String]。由于此特定数组指定了字符串的值类型,因此只允许存储字符串值。这里,shoppingList数组是用两个字符串值(“Eggs”和“Milk”)初始化的,这两个字符串值写在数组文本中。
由于Swift的类型推断,如果使用包含相同类型值的数组文本初始化数组,则不必编写数组的类型。shoppingList的初始化可以用更短的格式编写:var shoppingList = ["Eggs", "Milk"]
访问和修改Array
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 isn't empty.")
}
// Prints "The shopping list isn't empty."
shoppingList.append("Flour")
// shoppingList now contains 3 items
可以使用加法赋值运算符(+=)附加一个或多个兼容项的数组:
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"
还可以使用下标语法一次更改值范围,即使替换值集的长度与要替换的范围不同。以下示例将"Chocolate Spread", “Cheese”, 和"Butter"替换为"Bananas" and “Apples”:
shoppingList[4...6] = ["Bananas", "Apples"]
// shoppingList now contains 6 items
若要在指定索引处向数组中插入项,调用数组的insert(_:at:)
方法:
shoppingList.insert("Maple Syrup", at: 0)
// shoppingList now contains 7 items
// "Maple Syrup" is now the first item in the list
类似地,可以使用remove(_at:)
方法从数组中删除项。此方法删除指定索引处的项并返回删除的项(如果不需要,可以忽略返回的值):
let mapleSyrup = shoppingList.remove(at: 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
如果要从数组中删除最后一项,请使用removeLast()
方法而不是remove(_at:)方法,以避免查询数组的count属性。与remove(at:)方法类似,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
迭代Array
for item in shoppingList {
print(item)
}
// Six eggs
// Milk
// Flour
// Baking Powder
// Bananas
如果需要每个项的整数索引及其值,请改用enumerated()
方法迭代数组。对于数组中的每个项,enumerated()方法返回一个由整数索引和项组成的元组。整数索引从零开始,每项递增一;如果对整个数组进行枚举,则这些整数与项的索引匹配。作为迭代的一部分,你可以将元组分解为临时常量或变量:
for (index, value) in shoppingList.enumerated() {
print("Item \\(index + 1): \\(value)")
}
// Item 1: Six eggs
// Item 2: Milk
// Item 3: Flour
// Item 4: Baking Powder
// Item 5: Bananas
Sets
Set在没有定义顺序的集合中存储相同类型的不同值。如果项目的顺序不重要,或者需要确保项目只出现一次,则可以使用Set而不是Array。
Set类型的哈希值:
一个类型必须是可哈希的(hashable),才能存储在一个Set中,也就是说,该类型必须提供一种方法来为自己计算哈希值。哈希值是一个Int值,对于所有进行同等比较的对象来说都是相同的,因此如果a==b,则a的哈希值等于b的哈希值。
Swift的所有基本类型(如String、Int、Double和Bool)在默认情况下都是可哈希的,可以用作Set值类型或Dictionary键类型。默认情况下,没有关联值的枚举案例值也是可哈希的。
你可以使用自己的自定义类型作为Set值类型或Dictionary键类型,方法是使它们符合Swift标准库中的Hashable协议。
Set的类型写为Set<Element>,其中Element是允许Set存储的类型。与Array不同,Set没有等效的速记形式。
创建和初始化空Set
// 根据初始值设定项的类型,将letters变量的类型推断为Set\\<Character>。
var letters = Set<Character>()// set中是[字符类型]
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>
用数组字面量创建Set
var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]
// favoriteGenres has been initialized with three initial items
favoriteTyres集声明为变量(使用var导入器)而不是常量(使用let导入器),因为在下面的示例中添加和删除了项。
由于Swift的类型推断机制,所以上面代码可简化为:
var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"]
访问和修改Set
print("I have \\(favoriteGenres.count) favorite music genres.")
// Prints "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.")
}
// Prints "I have particular music preferences."
插入数据:favoriteGenres.insert("Jazz")
可以通过调用集合的remove(_:)
方法从集合中移除项,如果该项是集合的成员,则该方法将移除该项,并返回移除的值;如果集合不包含该项,则返回nil
。或者,可以使用其removeAll()
方法删除集合中的所有项。
if let removedGenre = favoriteGenres.remove("Rock") {
print("\\(removedGenre)? I'm over it.")
} else {
print("I never much cared for that.")
}
// Prints "Rock? I'm over it."
要检查集合是否包含特定项,请使用contains(_:)
方法。
if favoriteGenres.contains("Funk") {
print("I get up on the good foot.")
} else {
print("It's too funky in here.")
}
// Prints "It's too funky in here."
迭代Set
for genre in favoriteGenres {
print("\\(genre)")
}
// Classical
// Jazz
// Hip hop
Swift的Set类型没有定义的顺序。要按特定顺序迭代集合的值,请使用sorted()
方法,该方法将集合的元素返回为使用<运算符排序的数组。
for genre in favoriteGenres.sorted() {
print("\\(genre)")
}
// Classical
// Hip hop
// Jazz
执行Set的集合操作
● 使用intersection(_:)
方法创建一个新集合,该集合仅具有两个集合的公共值。
● 使用symmetricDifference(_:)
方法创建一个新集合,其中的值在任一集合中,但不能同时在两个集合中。
● 使用union(_:)
方法创建一个包含两个集合中所有值的新集合。
● 使用subtracting(_:)
方法创建一个值不在指定集合中的新集合。
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).sorted()
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
oddDigits.intersection(evenDigits).sorted()
// []
oddDigits.subtracting(singleDigitPrimeNumbers).sorted()
// [1, 9]
oddDigits.symmetricDifference(singleDigitPrimeNumbers).sorted()
// [1, 2, 9]
Set成员及相等
下图描述了三个集合a、b和c,其中重叠区域表示集合之间共享的元素。集合a是集合b的超集,因为a包含b中的所有元素。相反,集合b是集合a的子集,因为b中的所有元素也包含在a中。集合b和集合c彼此不相交,因为它们没有共同的元素。
● 使用“等于”运算符(=)确定两个集合是否包含所有相同的值。
● 使用isSubset(of:)
方法确定指定集合中是否包含集合的所有值。
● 使用isSuperset(of:)
方法确定集合是否包含指定集合中的所有值。
● 使用isStrictSubset(of:)
或isStrictSuperset(of:)
方法确定集合是指定集合的子集还是超集,但不等于指定集合。
● 使用isDisjoint(with:)
方法确定两个集合是否没有共同的值。
let houseAnimals: Set = ["🐶", "🐱"]
let farmAnimals: Set = ["🐮", "🐔", "🐑", "🐶", "🐱"]
let cityAnimals: Set = ["🐦", "🐭"]
houseAnimals.isSubset(of: farmAnimals)// true
farmAnimals.isSuperset(of: houseAnimals)// true
farmAnimals.isDisjoint(with: cityAnimals)// true
Dictionarys
Dictionary在没有定义顺序的集合中存储相同类型的键和相同类型的值之间的关联。每个值都与唯一键相关联,该键在字典中充当该值的标识符。与数组中的项不同,Dictionary中的项没有指定的顺序。当需要根据值的标识符查找值时,可以使用Dictionary,这与使用真实世界字典查找特定单词的定义的方式大致相同。
Swift Dictionary的类型完整地写为Dictionary<Key, Value>,其中Key是可以用作字典键的值的类型,Value是字典为这些键存储的值的类型。
字典Key类型必须符合Hashable协议,就像Set的值类型一样。
还可以将Dictionary的类型以速记形式写成[Key:Value]。尽管这两种形式在功能上是相同的,但速记形式是首选形式,在本指南中提及词典类型时使用速记形式。
创建一个空Dictionary
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]
用字面值创建Dictionary
形式为:[key1:value1, key2:value2, key3:value 3]
var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
由于Swift的类型推断机制,可以简化为:var airports = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
访问和修改Dictionary
print("The airports dictionary contains \\(airports.count) items.")
// Prints "The airports dictionary contains 2 items."
if airports.isEmpty {
print("The airports dictionary is empty.")
} else {
print("The airports dictionary isn't empty.")
}
// Prints "The airports dictionary isn't 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"
作为下标的替代方法,可以使用Dictionary的updateValue(_:forKey:)
方法设置或更新特定Key的值。与上面的下标示例一样,updateValue(_:forKey:)
方法为不存在的Key设置一个值,或者如果该Key已经存在,则更新该值。但是,与下标不同的是,updateValue(_:forKey:)
方法在执行更新后返回旧值。这使您能够检查是否发生了更新。
updateValue(_:forKey:)
方法返回Dictionary值类型的可选值。例如,对于存储String的Dictionary,该方法返回String?
类型的值,或“可选String”。此可选值包含该Key的旧值(如果更新之前存在),或者如果不存在值,则包含nil
:
if let oldValue = airports.updateValue("Dublin Airport", forKey: "DUB") {
print("The old value for DUB was \\(oldValue).")
}
// Prints "The old value for DUB was Dublin."
还可以使用下标语法从Dictionary中检索特定键的值。因为可以请求不存在值的键,所以Dictionary的下标返回Dictionary值类型的可选值。如果Dictionary包含请求键的值,则下标返回一个可选值,该值包含该键的现有值。否则,下标返回nil:
if let airportName = airports["DUB"] {
print("The name of the airport is \\(airportName).")
} else {
print("That airport isn't in the airports dictionary.")
}
// Prints "The name of the airport is Dublin Airport."
可以使用下标语法,通过为该键指定值nil,从字典中删除键值对:
airports["APL"] = "Apple International"
// "Apple International" isn't the real airport for APL, so delete it
airports["APL"] = nil
// APL has now been removed from the dictionary
或者,使用removeValue(forKey:)
方法从Dictionary中删除键值对。如果键值对存在,此方法将删除该键值对,并返回删除的值;如果不存在值,则返回nil:
if let removedValue = airports.removeValue(forKey: "DUB") {
print("The removed airport's name is \\(removedValue).")
} else {
print("The airports dictionary doesn't contain a value for DUB.")
}
// Prints "The removed airport's name is Dublin Airport."
迭代Dictionary
Dictionary中的每个项都作为(key, value)元组返回。
for (airportCode, airportName) in airports {
print("\\(airportCode): \\(airportName)")
}
// LHR: London Heathrow
// YYZ: Toronto Pearson
还可以通过访问Dictionary的keys
和values
属性来检索Dictionary键或值的可迭代集合:
for airportCode in airports.keys {
print("Airport code: \\(airportCode)")
}
// Airport code: LHR
// Airport code: YYZ
for airportName in airports.values {
print("Airport name: \\(airportName)")
}
// Airport name: London Heathrow
// Airport name: Toronto Pearson
如果需要将Dictionary的键或值与获取数组实例的API一起使用,请使用keys或values属性初始化新数组:
let airportCodes = [String](airports.keys)
// airportCodes is ["LHR", "YYZ"]
let airportNames = [String](airports.values)
// airportNames is ["London Heathrow", "Toronto Pearson"]
Swift的Dictionary类型没有定义的顺序。要按特定顺序迭代字典的键或值,请对其键或值属性使用sorted()
方法。
以上是关于➽03集合类型的主要内容,如果未能解决你的问题,请参考以下文章