Подтвердить что ты не робот

Как создать набор настраиваемых объектов (Swift)?

Для моего приложения iOS у меня есть модель, похожая на

class Person {
    var Id: Int
    var Name: String

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

Затем в моем 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"))
    }
}

То, что я теперь пытаюсь сделать, - превратить массив people в Set<Person>, чтобы он не добавлял дубликаты. Возможно ли это сделать или мне нужно изменить мою логику?

4b9b3361

Ответ 1

Чтобы создать набор Person, вам необходимо выполнить его соответствие протоколам Equalable и 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
}

Затем вы можете использовать набор таких людей:

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

Ответ 2

С Swift 2.0 Hashable и Equitable являются частью NSObject. Все, что вам нужно сделать, это переопределить "isEqual" и "var hash:" для интересующего свойства. В этом случае: "Id", Set будет исключать объекты Person с идентичными идентификаторами.

    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"}]

    }