Как создать набор настраиваемых объектов (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>
, чтобы он не добавлял дубликаты. Возможно ли это сделать или мне нужно изменить мою логику?
Ответы
Ответ 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"}]
}