當前位置: 首頁>>編程示例 >>用法及示例精選 >>正文


Swift Collection用法及代碼示例

協議

Collection

一個序列,其元素可以被多次、非破壞性地遍曆,並且可以通過索引下標訪問。

聲明

protocol Collection<Element> : Sequence

概述

集合在整個標準庫中被廣泛使用。當您使用數組、字典和其他集合時,您將從 Collection 協議聲明和實現的操作中受益。除了集合從 Sequence 協議繼承的操作之外,您還可以訪問依賴於訪問集合中特定位置的元素的方法。

例如,如果您隻想打印字符串中的第一個單詞,您可以搜索第一個空格的索引,然後創建一個直到該位置的子字符串。


let text = "Buffalo buffalo buffalo buffalo."
if let firstSpace = text.firstIndex(of: " ") {
    print(text[..<firstSpace])
}
// Prints "Buffalo"

firstSpace 常量是text 字符串的索引——字符串中第一個空格的位置。您可以將索引存儲在變量中,並將它們傳遞給集合算法或稍後使用它們來訪問相應的元素。在上麵的示例中,firstSpace 用於提取包含直到該索引的元素的前綴。

訪問單個元素

您可以使用集合的endIndex 屬性以外的任何有效索引,通過其下標訪問集合的元素。此屬性是一個“past the end” 索引,它與集合的任何元素都不對應。

下麵是一個通過下標訪問字符串中第一個字符的示例:


let firstChar = text[text.startIndex]
print(firstChar)
// Prints "B"

Collection 協議聲明並提供了許多操作的默認實現,這些操作依賴於可通過其下標訪問的元素。例如,您還可以使用first 屬性訪問text 的第一個字符,該屬性具有集合的第一個元素的值,或者如果集合為空,則為nil


print(text.first)
// Prints "Optional("B")"

您隻能將有效索引傳遞給集合操作。您可以通過從集合的startIndex 屬性開始並查找直到(包括)endIndex 屬性的每個後繼來找到一組完整的集合有效索引。 Index 類型的所有其他值,例如不同集合的startIndex 屬性,都是此集合的無效索引。

由於變異操作,保存的索引可能會變得無效。有關可變集合中索引失效的更多信息,請參閱MutableCollectionRangeReplaceableCollection 協議以及您正在使用的特定類型的參考。

訪問集合的切片

您可以通過其範圍下標或調用 prefix(while:)suffix(_:) 等方法來訪問集合的切片。集合的切片可以包含零個或多個原始集合的元素,並共享原始集合的語義。

下麵的示例通過使用prefix(while:) 方法創建firstWord 常量來獲取text 字符串的一部分。


let firstWord = text.prefix(while: { $0 != " " })
print(firstWord)
// Prints "Buffalo"

您可以使用字符串的範圍下標檢索相同的切片,該下標采用範圍表達式。


if let firstSpace = text.firstIndex(of: " ") {
    print(text[..<firstSpace]
    // Prints "Buffalo"
}

text 的檢索切片在每種情況下都是等效的。

切片股票指數

集合及其切片共享相同的索引。集合的元素位於切片中與基本集合中相同的索引下,隻要集合和切片自切片創建以來都沒有發生突變。

例如,假設您有一個數組,其中包含一個會話期間每個類的缺勤次數。


var absences = [0, 2, 0, 4, 0, 3, 1, 0]

你的任務是找出下半場缺勤最多的一天。要查找相關日期的索引,請執行以下步驟:

  1. 創建包含後半天的absences 數組的切片。

  2. 使用max(by:) 方法確定缺勤次數最多的一天的索引。

  3. 使用在步驟 2 中找到的原始 absences 數組上的索引打印結果。

以下是這些步驟的實現:


let secondHalf = absences.suffix(absences.count / 2)
if let i = secondHalf.indices.max(by: { secondHalf[$0] < secondHalf[$1] }) {
    print("Highest second-half absences: \(absences[i])")
}
// Prints "Highest second-half absences: 3"

切片繼承集合語義

切片繼承其基本集合的值或引用語義。也就是說,當使用具有值語義的可變集合的切片(例如數組)時,改變原始集合會觸發該集合的副本,並且不會影響切片的內容。

例如,如果您將 absences 數組的最後一個元素從 0 更新為 2 ,則 secondHalf 切片保持不變。


absences[7] = 2
print(absences)
// Prints "[0, 2, 0, 4, 0, 3, 1, 2]"
print(secondHalf)
// Prints "[0, 3, 1, 0]"

遍曆集合

盡管可以在遍曆序列時使用它,但可以保證集合是 multipass :任何元素都可以通過保存其索引來重複訪問。此外,集合的索引構成了集合元素位置的有限範圍。所有集合都是有限的這一事實保證了許多序列操作的安全性,例如使用contains(_:) 方法來測試集合是否包含元素。

按位置迭代集合的元素會產生相同的元素,其順序與使用其迭代器迭代該集合的順序相同。此示例演示了字符串的 characters 視圖以相同的順序返回相同的字符,無論是迭代視圖的索引還是視圖本身。


let word = "Swift"
for character in word {
    print(character)
}
// Prints "S"
// Prints "w"
// Prints "i"
// Prints "f"
// Prints "t"


for i in word.indices {
    print(word[i])
}
// Prints "S"
// Prints "w"
// Prints "i"
// Prints "f"
// Prints "t"

符合收集協議

如果您創建一個可以提供對其元素的重複訪問的自定義序列,請確保其類型符合Collection 協議,以便為序列和集合操作提供更有用和更有效的接口。要將Collection 一致性添加到您的類型,您必須至少聲明以下要求:

  • startIndexendIndex 屬性

  • 至少提供對類型元素的隻讀訪問權限的下標

  • index(after:) 將索引推進到集合中的方法

預期表現

符合 Collection 的類型應提供 startIndexendIndex 屬性和對元素的下標訪問,作為 O(1) 操作。不能保證這種性能的類型必須記錄偏離,因為許多收集操作依賴於 O(1) 下標性能來保證它們自己的性能。

某些集合操作的性能取決於集合提供的索引類型。例如,可以在 O(1) 時間內測量兩個索引之間的距離的隨機訪問集合可以在 O(1) 時間內計算其count 屬性。相反,由於前向或雙向集合必須遍曆整個集合以計算包含元素的數量,因此訪問其count 屬性是 O(n) 操作。

可用版本

iOS 8.0+, iPadOS 8.0+, macOS 10.10+, Mac Catalyst 13.0+, tvOS 9.0+, watchOS 2.0+

相關用法


注:本文由純淨天空篩選整理自apple.com大神的英文原創作品 Collection。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。