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

问题缘起

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,看看会发生什么,与你想象中一样吗?

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • SwiftDay011.MySwiftimport UIKitprintln("Hello Swift!")var...
    smile丽语阅读 4,061评论 0 6
  • MYSQL 基础知识 1 MySQL数据库概要 2 简单MySQL环境 3 数据的存储和获取 4 MySQL基本操...
    Kingtester阅读 8,041评论 5 115
  • 转载:http://www.jianshu.com/p/e70bd6645d88前言 熟悉Objective-C语...
    guoshengboy阅读 1,088评论 0 1
  • 前言 熟悉Objective-C语言的同学们肯定对协议都不陌生,在Swift中苹果将protocol这种语法发扬的...
    老板娘来盘一血阅读 7,048评论 7 44
  • 2018.2.28.星期三.晴.亲子日记第36天 哎! 又在医院里渡过了一天。昨天因抽血检查时间过了,今天...
    瑞泽成长记阅读 113评论 0 0

友情链接更多精彩内容