斯威夫特中的集结类型,斯维夫特语言中与C

这一部分的主要内容是Swift中的Collections

集合类型 (Collection Types)

自从苹果2014年发布Swift,到现在已经两年多了,而Swift也来到了3.1版本。去年利用工作之余,共花了两个多月的时间把官方的Swift编程指南看完。现在整理一下笔记,回顾一下以前的知识。有需要的同学可以去看官方文档>>。


Swift提供了三种集合类型:数组(Array)、集合(Set)、字典(Dictionary)。Array是有顺序的值的集合;Set是多个唯一的值的无序集合;Dictionary是无序的键值对集合。

注意:Swift的ArraySetDictionary都属于泛型集合。

Swift提供ArraysSetsDictionaries三种基本的集合类型用来存储集合数据。

我们知道Java中的Collection基本上是每一个Java程序猿接触到的第一个重要的知识点。

数组 (Array)

数组只能存储相同类型的值。相同的值可以出现在数组的不同位置中。

1. 数组

数组使用有序列表存储同一类型的多个值,相同的值可以多次出现。

在Swift中也不例外,Swift中的Collection有三个:数组(Array),字典(Dictionary)和集合(set)

数组类型的速记语法 (Array Type Shorthand Syntax)

一个数组的类型是这样写的:Array<Element>Element是数组元素值的类型,也可以简写成:[Element]

1.1 创建一个空数组

var someInts = [Int]()

一、数组

创建一个空数组 (Creating an Empty Array)
var someInt = [Int]()
print("someInts is of type [Int] with (someInts.count) items.")
// Prints "someInts is of type [Int] with 0 items."

someInt被推断为[Int]类型。

如果上下文已经提供了数组的类型,空素组还可以写成[]

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

1.2 创建一个带有默认值得数组

var threeDoubles = Array(repeating: 0.0, count: 3)
// 等价于[0.0, 0,0, 0.0]

数组的创建方法,请参考另外一篇文章Swift3中数组创建方法,这里要说的是Swift中一些数组的特性:

创建一个有默认值的数组 (Creating an Array with a Default Value)
var threeDoubles = Array(repeating: 0.0, count: 3)
// threeDoubles is of type [Double], and equals [0.0, 0.0, 0.0]

1.3 通过两个数组相加创建一个数组

var anotherThreeDoubles = Array(repeating: 2.5, count: 3)
var sixDoubles = threeDoubles   anotherThreeDoubles
// sixDoubles被推断为[Double]

1、向数组中添加元素:

通过合并两个数组来创建数组 (Creating an Array by Adding Two Arrays Together)
let 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]

1.4 用数组字面量构造数组

var shoppingList:[String] = ["Eggs", "Milk"]
// shoppingList已经被构造并且拥有两个初始项

由于Swift的类型推断机制,当我们用字面量构造只拥有相同类型值数组的时候,可以省却数组的类型:

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

向数组中添加元素除了可以使用append方法,使用 也是可以的:

用字面值创建数组 (Creating an Array with an Array Literal)
var shoppingLis = ["Eggs", "Milk"]
// shoppingList has been initialized with two initial items

1.5 访问和修改数组

  • count:获取数组中的元素数目
  • isEmpty:检查count是否为0
  • append(_:):在数组后面添加新的数据
  • insert(_:at:):在某个具体索引值之前添加数据项
  • remove(at:):移除数组中的某一项
  • removeLast():移除数组的最后一项

=运算符可以直接在数组后面添加一个或多个同类型的数据项:

shoppingList  = ["Baking Powder"]
shoppingList  = ["Chocolate Spread", "Cheese", "Butter"]

我们可以通过下标获取或改变某个已有索引值对应的数据。
还可以利用下标来一次改变一系列的数据值:

shoppingList[4..<6] = ["Bananas", "Apples"]
var numbers = [1,2,3,4,5]
numbers.append(8)
numbers [8]
访问和修改数组 (Accessing and Modifying an Array)

获取数组的个数:

print("The shopping list contains (shoppingList.count) items.")
// Prints "The shopping list contains 2 items."

判断数组元素的个数是否为0:

if shoppingList.isEmpty {
    print("The shopping list is empty.")
} else {
    print("The shopping list is not empty.")
}

追加一个元素:

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"

使用下标一次性更改多个元素,甚至要更改的元素个数可以不等于新数组的个数:

shoppintList[4...6] = ["Bananas", "Apples"]
// 用两个替换三个

在特定的位置插入元素:

shoppingList.insert("Maple syrup", at: 0)
// shoppingList now contains 7 items
// "Maple Syrup" is now the first item in the list

删除特定位置的元素,并且返回被删除的元素:

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

删除最后一个元素:

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

1.6 数组的遍历

我们可以用for-in循环遍历所有数组中的数据项。
如果我们同时需要每个数据项的值和索引值,可以使用enumerated()方法。enumerated()返回一个由每一个数据项索引值和数据值组成的元组:

for (index, value) in shoppingList.enumerated() {
    print("Item (String(index   1)): (value)")
}

都是可以的。

遍历整个数组 (Iterating Over an Array)

使用for-in遍历:

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

使用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

2. 集合

集合用来存储相同类型并且没有确定顺序的值,集合内的元素不能重复。

2、两个数组相等

集合 (Sets)

集合中无顺序地存储了同一类型的值,并且里面的每一个值都是唯一的。在元素的顺序不重要或者要求每一个元素都需要唯一的时候,可以使用集合,而不用数组。

2.1 集合类型的哈希值

存储在集合中的类型必须是可哈希化的,Swift的所有基本类型(比如String,Int,DoubleBool)默认都是可哈希化的,没有关联值额枚举成员值默认也是可哈希化的。

你可以使用自定义的类型作为集合的值的类型或字典的键的类型,但需要使自定义类型符合Swift标准库中的Hashable协议。符合Hashable协议的类型需要提供一个类型为Int的可读属性hashValue

在Java和C/C 中判断两个数组相等是比较复杂的,但是在Swift中却很方便:

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

集合里面的元素类型必须hashable,也就是说,这个元素类型必须提供一个方法来计算他自己的哈希值。一个哈希值是一个用来判断两个对象是否相等的Int类型的整数。例如,如果a == b,那么a.hashValue == b.hashValue

所有Swift的基本类型(例如StringIntDoubleBool)默认都是hashable的,都可以作为集合的值类型或者字典的键类型。没有关联值的枚举值默认也是hashable的。

我们可以自定义类型,并且遵循Hashable协议,作为集合或者字典键的值类型。自定义的类型必须提供一个能读取的Int类型的属性,并命名为hashValue。在不同的程序或者同一个程序运行多次中,不要求每次hashValue属性返回的值都相等。

因为Hashable协议遵循Equatable协议,所以我们自定义的类型还需要提供一个相等运算符(==)的实现。Equatable协议要求每一个==的实现是一个等价关系。也就是说,==的实现必须满足下面三个条件:

  • a == a (自反性)
  • a == b,说明b == a (对称性)
  • a == b && b == c,说明 a == c (传递性)

2.2 集合类型语法

var numbers = [1,2,3,4,5]
var oneToFive = [1,2,3,4,5]
numbers == oneToFive
集合类型语法 (Set Type Syntax)

使用Set<Element>来设置集合类型,Element是集合存储的元素类型。

2.2.1 创建和构造一个空的集合

var letters = Set<Character>()

这个返回值就是true,直接用==就可以进行判断了。

创建和初始化一个空集合 (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被推断为Set<Character>类型。

同样地,如果上下文提供了集合的类型信息,可以使用[]来创建一个空的集合:

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>

2.2.2 用数组字面量创建集合

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

二、字典和集合

使用数组字面值来创建一个集合 (Creating a Set with an Array Literal)
var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]
// favoriteGenres has been initialized with three initial items

集合的类型不能通过数组的字面值来推断,所以Set的类型必须明确声明。但是因为Swift的类型推断,如果用一个包含相同类型字面值的数组来初始化集合,我们可以不写集合的类型。例如:

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

因为数组的全部字面值都是同一类型,所以Swfit能推断出Set<String>favoriteGenres的正确类型。

2.2.3 访问和修改一个集合

  • count:返回Set中元素的数量
  • isEmpty:检查count是否为0
  • insert(_:):添加一个新元素
  • remove(_:):删除一个元素(如果Set不包含该值,返回nil)
  • removeAll():删除所有元素
  • contains(_:):检查Set中是否包含一个特定的值

对字典和集合来说最重要的是创建方法,其他的在官方文档都可以查到(当然创建方法也是可以查到的)

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

使用count属性获取集合元素个数:

print("I have (favoriteGenres.count) favorite music genres.")
// Prints "I have 3 favorite music genres."

使用isEmpty属性判断集合中元素的个数是否为0:

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."

使用insert(_:)方法添加元素:

favoriteGenres.insert("Jazz")
// favoriteGenres now contains 4 items

使用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."

判断是否包含某个元素:

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."

2.2.4 遍历一个集合

使用for-in遍历一个集合。
Swift的Set类型没有确定的顺序,为了按照特定的顺序来遍历一个Set中的值可以用sorted()方法,它将返回一个有序数组,这个数组的元素排列顺序又操作符<对元素进行比较的结果来确定 。

for genre in favoriteGenres.sorted() {
    print("genre")
}
// 按顺序打印"Classical", "Hip hop", "Jazz"

字典的创建:

遍历整个集合 (Iterating Over a Set)
for genre in favoriteGenres {
    print("(genre)")
}
// Jazz
// Hip hop
// Classical

Swift的集合类型没有定义顺序,我们可以使用sorted()方法来排序,这个方法使用<运算符将元素从小到大排列:

for genre in favoriteGenres.sorted() {
    print("(genre)")
}
// Classical
// Hip hop
// Jazz

2.3 集合操作

var dic = ["apple" : "苹果", "bag" : "包"]

执行集合操作 (Performing Set Operations)

2.3.1 基本集合操作

  • 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]

集合的创建:

基本集合操作 (Fundamental Set Operations)

下图是集合ab执行了不同的方法之后,得出的结果图:

图片 1

Fundamental Set Operations

  • 使用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]

2.3.2 集合成员关系和相等

  • ==:判断两个集合是否相等
  • isSubset(of:):判断一个集合中的值是否也被包含在另一个集合中
  • isStrictSubset(of:)/isStrictSuperset(of:):判断一个集合是否是另一个集合的子集合/父集合并且两个集合不相等
  • isDisjoint(with:):判断那两个集合是否有交集
let houseAnimals: Set = ["dog", "cat"]
let farmAnimals: Set = ["cow", "chicken", "sheep", "dog", "cat"]
let cityAnimals: Set = ["bird", "mouse"]

houseAnimals.isSubset(of: farmAnimals)
// true

farmAnimals.isSuperset(of: houseAnimals)
// true

farmAnimals.isDisjoint(with: cityAnimals)
// ture
var letters = Set<Character>()
var setColors:Set<String> = ["红色","白色","洋红色","黄色"]
集合关系和相等性 (Set Membership and Equality)

下图演示了三个集合:abc,重叠区域代表有相同的元素。集合a是集合b的父集合,因为a包含了b的所有元素;相反,ba的子集合。集合b和集合c互不相交,因为他们没有相同的元素。

图片 2

Set Membership and Equality

  • 使用“是否相等”运算符 (==)来判断两个集合的所有元素是否相等
  • 使用isSubset(of:)方法判断集合的所有元素是否包含于指定集合
  • 使用isSuperset(of:)方法判断集合是否包含指定集合的所有元素
  • 使用isStrictSubset(of:)或者isStrictSuperset(of:)方法判断集合是否子集合或者父集合,但是不等于指定的集合
  • 使用isDisjoint(with:)方法判断两个集合是否有相同的元素
let houseAnimals: Set = ["
			

本文由星彩网app下载发布于计算机编程,转载请注明出处:斯威夫特中的集结类型,斯维夫特语言中与C

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。