美文网首页
Swift 5.x Set 访问和修改

Swift 5.x Set 访问和修改

作者: ShenYj | 来源:发表于2020-06-25 23:11 被阅读0次

    1.遍历 Set

    • 可以使用for-in遍历Set
    • 因为Set是无序的, 如果要顺序遍历Set, 使用sorted()方法

    let courses: Set = ["Math", "English", "History"]
    for course in courses {
        print(course)
    }
    print("--- 分割线 ---")
    for course in courses.sorted() {
        print(course)
    }
    
    

    输出结果:

    English   
    History
    Math
    --- 分割线 ---
    English
    History
    Math
    

    2. 访问Set

    • 使用count获取Set里元素个数
    • 使用isEmpty判断Set是否为空

    let set: Set<Character> = ["A", "B", "C"]
    print(set.count)
    print(set.isEmpty)
    

    输出结果:

    3
    false
    

    3. 添加元素

    • insert(_:)添加一个元素到Set
    • update(with:)如果已经有相等的元素(哈希一样), 替换为新元素. 如果Set中没有, 则插入.

    struct Person {
        var name: String = ""
        var age: Int = 0
    }
    extension Person: Hashable {
        func hash(into hasher: inout Hasher) {
            hasher.combine(name)
        }
    }
    extension Person: Equatable {
        static func == (lhs: Person, rhs: Person) -> Bool {
            return lhs.name == rhs.name
        }
    }
    
    var personSet: Set<Person> = [
        Person(name: "zhangsan", age: 23),
        Person(name: "lisi", age: 20)
    ]
    personSet.update(with: Person(name: "zhangsan", age: 24))
    print(personSet)
    

    这里的Person 只计算name的哈希值, 并且只根据name判断两个Person对象是否相等

    输出结果:

    [
    __lldb_expr_148.Person(name: "zhangsan", age: 24), 
    __lldb_expr_148.Person(name: "lisi", age: 20)
    ]
    

    由于这里只计算name的哈希值, 所以执行udpate时, 将原有的数据进行了更新, 而没有新增

    如果改成

    hasher.combine(name)
    hasher.combine(age)
    

    则会新增一条记录

    [
    __lldb_expr_150.Person(name: "zhangsan", age: 23), 
    __lldb_expr_150.Person(name: "zhangsan", age: 24), 
    __lldb_expr_150.Person(name: "lisi", age: 20)
    ]
    
    

    4. 移除元素

    • 4.1 filter(_:)返回一个新的Set, 新Set的元素是原始Set符合条件的元素.

    struct Person {
        var name: String = ""
        var age: Int = 0
    }
    extension Person: Hashable {
        func hash(into hasher: inout Hasher) {
            hasher.combine(name)
            hasher.combine(age)
        }
    }
    extension Person: Equatable {
        static func == (lhs: Person, rhs: Person) -> Bool {
            return lhs.name == rhs.name
        }
    }
    
    var personSet: Set<Person> = [
        Person(name: "zhangsan", age: 23),
        Person(name: "lisi", age: 20),
        Person(name: "wangwu", age: 27)
    ]
    let filterdSet = personSet.filter({$0.age < 25})
    print(filterdSet)
    

    输出结果:

    [
    __lldb_expr_152.Person(name: "zhangsan", age: 23), 
    __lldb_expr_152.Person(name: "lisi", age: 20)
    ]
    
    • 4.2 remove(_:)Set当中移除一个元素, 如果元素是Set的成员就移除它, 并且返回移除的值, 如果集合没有这个成员就返回nil
    struct Person {
        var name: String = ""
        var age: Int = 0
    }
    extension Person: Hashable {
        func hash(into hasher: inout Hasher) {
            hasher.combine(name)
            hasher.combine(age)
        }
    }
    extension Person: Equatable {
        static func == (lhs: Person, rhs: Person) -> Bool {
            return lhs.name == rhs.name
        }
    }
    
    var personSet: Set<Person> = [
        Person(name: "zhangsan", age: 23),
        Person(name: "lisi", age: 20),
        Person(name: "wangwu", age: 27)
    ]
    let removedElement: Person? = personSet.remove(Person(name: "zhangsan", age: 22))
    print(removedElement ?? "集合不存在该元素")
    

    由于age在哈希值计算范围内, 所以打印结果为

    集合不存在该元素
    

    如果去掉hasher.combine(age)这一行代码, 打印结果:

    Person(name: "zhangsan", age: 23)
    
    • 4.3 removeAll() 移除所有元素

    personSet.removeAll()
    print(personSet)
    

    输出结果:

    []
    
    • 4.4 removeFirst() 移除Set的第一个元素, 因为Set是无序的, 所以第一个元素并不是放入的第一个元素, 而是哈希计算排序后的第一个元素.

    struct Person {
        var name: String = ""
        var age: Int = 0
    }
    extension Person: Hashable {
        func hash(into hasher: inout Hasher) {
            hasher.combine(name)
        }
    }
    extension Person: Equatable {
        static func == (lhs: Person, rhs: Person) -> Bool {
            return lhs.name == rhs.name
        }
    }
    
    var personSet: Set<Person> = [
        Person(name: "zhangsan", age: 23),
        Person(name: "lisi", age: 20),
        Person(name: "wangwu", age: 27)
    ]
    personSet.removeFirst()
    print(personSet)
    

    输出结果:

    [
    __lldb_expr_175.Person(name: "lisi", age: 20), 
    __lldb_expr_175.Person(name: "wangwu", age: 27)
    ]
    

    5. 基于Set操作的

    • 5.1 intersection(_:) 交集, 由属于A且属于B的相同元素组成的集合, 记作AnBBnA


    • 5.2 union(_:) 并集, 由所有属于集合A或属于集合B的元素所组成的集合, 记作AuBBuA


    • 5.3 symmetricDifference(_:) 对称差集, 集合A与集合B中所有不属于AnB的元素的集合.


    • 5.4 subtracting(_:) 相对补集, 由属于A而不属于B的元素组成的集合, 成为B关于A的相对补集, 记作A-BA\B


    e.g.

    let set1: Set<Character> = ["A", "B", "C"]
    let set2: Set<Character> = ["B", "E", "F", "G"]
    print("交集 AnB: " + set1.intersection(set2))
    print("并集 AuB: " + set1.union(set2))
    print("对称差集: " + set1.symmetricDifference(set2))
    print("相对补集 A-B: " + set1.subtracting(set2))```
    

    输出结果:

    交集 AnB: B
    并集 AuB: FGBCAE
    对称差集: GCEAF
    相对补集 A-B: AC
    

    5. Set判断方法

    • isSubset(of:) 判断是否是另外一个Set或者Sequence的子集

    • isSuperset(of:) 判断是否是另外一个Set或者Sequence的超集

    • isStrictSubset(of:)isStrictSuperset(of:) 判断是否是另外一个Set的子集或者超集, 但是又不等于另外一个Set

    • isDisjoint(with:) 判断两个Set 是否有公共元素, 如果没有返回true, 如果有返回false

    let smallSet: Set = [1, 2, 3]
    let bigSet: Set = [1, 2, 3, 4]
    print(smallSet.isSubset(of: bigSet))
    print(bigSet.isSuperset(of: smallSet))
    print(smallSet.isStrictSubset(of: bigSet))
    print(bigSet.isStrictSuperset(of: smallSet))
    print(smallSet.isDisjoint(with: bigSet))
    

    输出结果:

    true
    true
    true
    true
    false
    

    相关文章

      网友评论

          本文标题:Swift 5.x Set 访问和修改

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