ios 如何创建一组自定义对象 (Swift)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32425886/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 07:31:43  来源:igfitidea点击:

How do I create a Set of custom objects (Swift)?

iosswiftsetequatable

提问by egor.zhdan

For my iOS app I have a model something like

对于我的 iOS 应用程序,我有一个类似的模型

class Person {
    var Id: Int
    var Name: String

    init(id: Int, name: String?) {
        self.Id = id
        self.Name = name ?? ""
    }
}

Then later on in my ViewControllerwhen I load data from the server I add some people to an array

然后ViewController当我从服务器加载数据时,我将一些人添加到数组中

class ViewController: UIViewController {
    var people:[Person] = []

    override func viewDidLoad() {
        self.loadPeople()
    }

    func loadPeople() {
        // This data will be coming from a server request
        // so is just sample. It could have users which 
        // already exist in the people array

        self.people.append(Person(id: "1", name: "Josh"))
        self.people.append(Person(id: "2", name: "Ben"))
        self.people.append(Person(id: "3", name: "Adam"))
    }
}

What I am now trying todo is turn the peoplearray into a Set<Person>so it will not add duplicates. Is this possible to do or do I need to change my logic?

我现在要做的是将people数组转换为 aSet<Person>以便它不会添加重复项。这是可能的还是我需要改变我的逻辑?

回答by egor.zhdan

To make set of Personyou need to make it conform to Equatable and Hashable protocols:

要进行设置,Person您需要使其符合 Equatable 和 Hashable 协议:

class Person: Equatable, Hashable {
    var Id: Int
    var Name: String

    init(id: Int, name: String?) {
        self.Id = id
        self.Name = name ?? ""
    }

    var hashValue: Int {
        get {
            return Id.hashValue << 15 + Name.hashValue
        }
    }
}

func ==(lhs: Person, rhs: Person) -> Bool {
    return lhs.Id == rhs.Id && lhs.Name == rhs.Name
}

Then you can use set of persons like this:

然后你可以使用这样的一组人:

var set = Set<Person>()
set.insert(Person(id: 1, name: "name"))

回答by Tom Tallak Solbu

With Swift 2.0, Hashable and Equitable is a part of NSObject. All you need to do is to override "isEqual" and "var hash:" for the property of interest. In this case: "Id", Set will exclude Person-objects with identical Ids.

在 Swift 2.0 中,Hashable 和 Equitable 是 NSObject 的一部分。您需要做的就是覆盖感兴趣的属性的“isEqual”和“var hash:”。在这种情况下:“Id”,Set 将排除具有相同 Id 的 Person-objects。

    class Person: NSObject {
        var Id: Int
        var Name: String

        init(id: Int, name: String?) {
            self.Id = id
            self.Name = name ?? ""
        }

        override var hash: Int {
        return Id.hashValue
   }

        override func isEqual(object: AnyObject?) -> Bool {
            guard let rhs = object as? Person else {
                return false
            }
            let lhs = self

            return lhs.Id == rhs.Id
        }


    }

          func mergeArrays(){
       let person1 = Person(id: 1, name: "Tom")
       let person2 = Person (id: 2, name: "John")
       let person3 = Person(id: 3, name: "Adam")


       let downloadedPeople  = [person1,person2] //[{NSObject, Id 1, Name "Tom"}, {NSObject, Id 2, Name "John"}] 

       let peopleStoredLocally = [person1,person3] //[{NSObject, Id 1, Name "Tom"}, {NSObject, Id 3, Name "Adam"}]

       let downloadedPeopleSet = Set(downloadedPeople) //{{NSObject, Id 2, Name "John"}, {NSObject, Id 1, Name "Tom"}}


       let mergedSet = downloadedPeopleSet.union(peopleStoredLocally) //{{NSObject, Id 2, Name "John"}, {NSObject, Id 3, Name "Adam"}, {NSObject, Id 1, Name "Tom"}}


       let mergedArray = Array(mergedSet)//[{NSObject, Id 2, Name "John"}, {NSObject, Id 3, Name "Adam"}, {NSObject, Id 1, Name "Tom"}]

    }