0

After realizing that Swift does not know how to compare pairs of numbers (made as tuples of Int). I have defined a class with the following code:

import Foundation

class NumberPair: NSObject {
    var row,column:Int!

    init(_ theRow: Int, _ theCol: Int) {
        row = theRow
        column = theCol
        super.init()
    }

    convenience override init() {
        self.init(0,0)
    }

    static func == (lhs: NumberPair, rhs: NumberPair) -> Bool {
        return (lhs.row == rhs.row) && (lhs.column == rhs.column)
    }

    static func != (lhs: NumberPair, rhs: NumberPair) -> Bool {
        return (lhs.row != rhs.row) || (lhs.column != rhs.column)
    }
}

Then when using the class I have something like this:

var firstArray = [NumberPair](), secondArray = [NumberPair]()
...........................
// Some code working fine that fills up firstArray and secondArray.
...........................

for pairItem in firstArray {
    if secondArray.index(of: pairItem) != nil {
        print("We found an item that is in both arrays.")
        break
    }
}

Now my question is this. The code a bove does not work. I mean, eventhough I am certain the 2 arrays firstArray and secondArray contains common pairs of numbers, the message never gets printed. What is wrong? Am I missing something obvious? Any hint will be very much appreciated.

Hamish
  • 78,605
  • 19
  • 187
  • 280
Michel
  • 10,303
  • 17
  • 82
  • 179
  • See point #2 of http://stackoverflow.com/a/42286148/2976878 – subclasses cannot reimplement their superclass' (`NSObject`) implementation of a protocol (`Equatable`). The solution, as already stated, it to override `isEqual(_:)` (you should also override `hash` too). – Hamish Mar 23 '17 at 10:18
  • @Hamish great answer. – Vishal Singh Mar 25 '17 at 15:35

1 Answers1

1

Use isEqual if you really want to inherit NSObject.

    class NumberPair: NSObject {
    public var row,column:Int!

    init(_ theRow: Int, _ theCol: Int) {
        row = theRow
        column = theCol
        super.init()
    }

    override func isEqual(_ object: Any?) -> Bool {
        guard let comparingObject = object as? NumberPair else {
            return false
        }
        return row == comparingObject.row && column == comparingObject.column
    }
}

Either above, or just drop inheritance from NSObject and conform to Equatable protocol.

class NumberPair: Equatable {
    public var row,column:Int!

    init(_ theRow: Int, _ theCol: Int) {
        row = theRow
        column = theCol
        //super.init()
    }



    static func == (lhs: NumberPair, rhs: NumberPair) -> Bool {
        return (lhs.row == rhs.row) && (lhs.column == rhs.column)
    }

    static func != (lhs: NumberPair, rhs: NumberPair) -> Bool {
        return (lhs.row != rhs.row) || (lhs.column != rhs.column)
    }
}
Vishal Singh
  • 4,400
  • 4
  • 27
  • 43
  • Great it works. I had found about == on the net but not about isEqual. Maybe I was not searching the right way. So now I see that implementing Equatable myself and inheriting from NSObject are 2 ways of addressing the problem. – Michel Mar 23 '17 at 09:13