Complete guide on custom class/struct comparison
Last updated on

Complete guide on custom class/struct comparison

iOS
iOSSwift#Import 2025-05-27 00:21

In Swift, you can either use class or struct to define your custom class. Most likely in the later development, you would need to have an array of such custom modelsomewhere in the project, and each of the custom model in the array are unique, in other words, you want an array/dictionary/set only includes non-duplicated custom model objects. So the following are the complete guide of some examples showing how to do compare your own custom model:

In Swift, you can either use class or struct to define your custom class. Here are some examples.

Struct Model

// Struct
struct NoteModel {
    let userName: String
    let latitude: Double
    let longitude: Double
    let text: String
    let createDateTime: String
}

In the case above, we are assuming if two notes have different username, latitude, longitude and text, they are two different notes, so if you want to make two of above objects can be comparable, add the following code:

struct NoteModel: Equatable {
    let userName: String
    let latitude: Double
    let longitude: Double
    let text: String
    let createDateTime: String
// compare whether two notes are same
static func == (lhs: NoteModel, rhs: NoteModel) -> Bool {
    return lhs.createDateTime == rhs.createDateTime &&
        lhs.text == rhs.text &&
        lhs.userName == rhs.userName &&
        lhs.latitude == rhs.latitude &&
        lhs.longitude == rhs.longitude
}

}

Class Model

Sometimes we are using class for the model, see the following code for the same functionality:

class NoteModel: Equatable {

let userName: String
let latitude: Double
let longitude: Double
let text: String
let createDateTime: String

init(userName: String, latitude: Double, longitude: Double, text: String, createDateTime: String) {
    self.userName = userName
    self.latitude = latitude
    self.longitude = longitude
    self.text = text
    self.createDateTime = createDateTime
}

static func == (lhs: NoteModel, rhs: NoteModel) -> Bool {
    return lhs.createDateTime == rhs.createDateTime &&
        lhs.text == rhs.text &&
        lhs.userName == rhs.userName &&
        lhs.latitude == rhs.latitude &&
        lhs.longitude == rhs.longitude
}

}

Class Model inherited from NSObject

Sometimes we have the special requirements that model class must inherited from NSObject, so you have to override the isEqual. See the following code for the same functionality:

class NoteModel: NSObject {

let userName: String
let latitude: Double
let longitude: Double
let text: String
let createDateTime: String

init(userName: String, latitude: Double, longitude: Double, text: String, createDateTime: String) {
    self.userName = userName
    self.latitude = latitude
    self.longitude = longitude
    self.text = text
    self.createDateTime = createDateTime
}

override func isEqual(_ object: Any?) -> Bool {
    guard let _object = object else { return false }
    guard let rhs = _object as? NoteModel else { return false }
    return (self.createDateTime == rhs.createDateTime &&
        self.text == rhs.text &&
        self.userName == rhs.userName &&
        self.latitude == rhs.latitude &&
        self.longitude == rhs.longitude
    )
}

}

Why do we need to override?

With overriding isEqual or ==, you can make use a lot of inner-built methods such as contains, filter etc, an example of showing contains:

let note1 = NoteModel(userName: “testing user 2”, latitude: 0.0, longitude: 0.0, text: “testing notes”, createDateTime: “04/12/2020 18:12:03”)
let note2 = NoteModel(userName: “testing user 2”, latitude: 0.0, longitude: 0.0, text: “testing notes”, createDateTime: “04/12/2020 18:12:03”)
let array = [note1]
XCTAssertEqual(array.contains(note2), true)  // true

Conclusion

  • Custom Struct/Class: need to extend Equatable and override the operand ==.
  • Custom Class inherited from NSObject: need to override isEqual.