美文网首页Objective C开发
Swift-存储类型-集合

Swift-存储类型-集合

作者: Joker_King | 来源:发表于2016-11-19 11:16 被阅读18次

    集合在集合中存储相同类型的不同值,没有定义的顺序。 当元素的顺序不重要时,或者当您需要确保元素只出现一次时,您可以使用集合而不是数组。

    集类型的哈希值

    类型必须是可哈希的,以便存储在集合中,即,类型必须提供一种计算自身的哈希值的方法。 哈希值是一个Int值,对于所有均等比较的对象是相同的,因此如果a == b,则遵循a.hashValue == b.hashValue。

    Swift的所有基本类型(例如String,Int,Double和Bool)在默认情况下是哈希的,并且可以用作设置值类型或字典键类型。 默认情况下,没有关联值的枚举值值(如枚举中所述)也是可哈希的。

    您可以使用自己的自定义类型作为设置值类型或字典键类型,使它们符合Swift标准库中的Hashable协议。 符合Hashable协议的类型必须提供一个称为hashValue的gettable Int属性。 由类型的hashValue属性返回的值不需要在同一程序的不同执行或不同程序中相同。

    因为Hashable协议符合Equatable,符合类型还必须提供equals运算符(==)的实现。 可等式协议要求任何符合的==的实现是等价关系。 也就是说,对于所有值a,b和c,==的实现必须满足以下三个条件:

    a == a (Reflexivity)
    
    a == b implies b == a (Symmetry)
    
    a == b && b == c implies a == c (Transitivity)
    

    集合类型的语法

    Swift集合的类型写为Set <Element>,其中Element是允许集合存储的类型。 与数组不同,集合没有等效的字面量。

    创建并初始化一个空集合

    您可以使用初始化语法创建一个特定类型的空集:

    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>
    

    使用数组创建集合

    您还可以使用数组文本初始化集合,作为将一个或多个值写入集合集合的简写方法。

    下面的示例创建一个名为favoriteGenres的集合来存储字符串值:

    var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]
    // favoriteGenres has been initialized with three initial items
    

    favoriteGenres变量被声明为“一组字符串值”,写为Set <String>。 因为此特定集合已指定值类型的字符串,它只允许存储字符串值。 这里,favoriteGenres集合使用在数组文本中写入的三个String值(“Rock”,“Classical”和“Hip Hop”)初始化。

    集合类型不能从数组文字单独推断,因此必须显式声明类型Set。 但是,由于Swift的类型推断,如果使用包含相同类型值的数组文本来初始化它,则不必编写集合的类型。 favoriteGenres的初始化可以写成更短的形式:

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

    访问和修改集合

    您可以通过其方法和属性访问和修改集合。

    要了解集合中的元素个数,请是有那个其只读计数属性:

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

    使用布尔isEmpty属性作为检查count属性是否等于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."
    

    您可以通过调用set的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."
    

    要检查集合是否包含特定项目,请使用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."
    

    遍历集合

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

    Swift的Set类型没有定义的顺序。 要以特定顺序迭代集合的值,请使用sorted()方法,该方法将使用数组的<operator运算符排序的集合的元素并返回。

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

    执行集合的操作

    您可以有效地执行基本集合操作,例如将两个集合组合在一起,确定两个集合具有共同的值,或者确定两个集合是否包含所有,一些或没有相同的值。

    集合的基本操作

    下面的图示描绘了两个集合a和b,其具有由阴影区域表示的各种集合操作的结果。


    屏幕快照 2016-11-19 上午11.05.07.png
    • 使用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]
    

    集合之间的关系

    下面的图示描绘了三个集合a,b和c,其中重叠区域表示在集合中共享的元素。 设置a是集合b的超集,因为a包含b中的所有元素。 相反,集合b是集合a的子集,因为b中的所有元素也包含在a中。 集合b和集合c彼此不相交,因为它们不共享公共的元素。


    屏幕快照 2016-11-19 上午11.12.17.png
    • 使用“is equal”运算符(==)来确定两个集合是否包含所有相同的值。
    • 使用isSubset(of :)方法来确定集合的所有值是否都包含在指定的集合中。
    • 使用isSuperset(of :)方法来确定集合是否包含指定集合中的所有值。
    • 使用isStrictSubset(of :)或isStrictSuperset(of :)方法来确定集合是否为子集或超集,但不等于指定的集合。
    • 使用isDisjoint(with :)方法来确定两个集合是否具有任何共同的值。
    houseAnimals.isSubset(of: farmAnimals)
    // true
    farmAnimals.isSuperset(of: houseAnimals)
    // true
    farmAnimals.isDisjoint(with: cityAnimals)
    // true
    

    相关文章

      网友评论

        本文标题:Swift-存储类型-集合

        本文链接:https://www.haomeiwen.com/subject/koospttx.html