美文网首页iOS学习开发程序员iOS学习笔记
NSSet 去重技巧:判断自定义类的相等

NSSet 去重技巧:判断自定义类的相等

作者: 溪石iOS | 来源:发表于2019-01-16 22:45 被阅读27次

    问题缘起

    Set 有个天然属性,就是放入的元素不能重复,这个特性也被常用于去除重复数据:

    var set:Set = ["1", "2", "3", "4", "1", "1"]
    print("set:\(set)") //输出为:set:["2", "1", "3", "4"]
    

    系统类可以很方便地放入Set,那么自定义类呢?
    假设需要自定义Person类,有个name属性,这里我们假设名字相同的人只有一个,所以逻辑上name相同的对象,在Set中只能有一个,但对于对象来说,两个实例是不同的指针,是不同的:

    class Person {
        var name:String
        init(name:String) {
            self.name = name
        }
    }
    var x1:Person? = Person(name:"Xishi")
    var x2:Person? = Person(name:"Xishi")
    var set:Set<Person?> = [x1, x2]
    

    实际上,以上代码无法通过编译:

    'Set' requires that 'Person' conform to 'Hashable'
    

    解决方案

    Swift 要求放入Set的类实现Hashable 协议,而Hashable本身又继承了Equatable协议,所以这里要同时实现两个协议:

    class Person : Hashable {
        var name:String
        init(name:String) {
            self.name = name
        }
    
        public var hashValue : Int {
            get {
                return self.name.hashValue
            }
        }
    
        static func ==(lhs: Person, rhs: Person) -> Bool {
            return lhs.name == rhs.name
        }
    }
    
    • public var hashValue : Int是Hashable协议要求的,需要返回能代表对象的哈希值,这里正好利用 String 的哈希值。
    • 看起来怪怪的static func ==(lhs: Person, rhs: Person) -> Bool方法声明是运算符重载,这里把==当作方法名就好理解了,相当于替换了一个名叫==的方法。

    这样,放入Set后,就能正常去除重复对象了。

    小实验

    == 方法改为固定返回 false,看看会发生什么,与你想象中一样吗?

    相关文章

      网友评论

        本文标题:NSSet 去重技巧:判断自定义类的相等

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