1

I have following code in Playgraound which doesn't work as I wish.

class Obj: NSObject {
    var va1: String? = nil
    var va2: Int? = nil
    init(_ v1: String,_ v2: Int){
        va1 = v1
        va2 = v2
    }

    static func ==(lhs: Obj, rhs: Obj) -> Bool {
        guard lhs.va1 == rhs.va1 else { return false }
        guard lhs.va2 == rhs.va2 else { return false }
        return true
    }
}

var objArray1: [Obj] = [Obj("a", 1), Obj("b", 2), Obj("c", 3)]
var objArray2: [Obj] = [Obj("a", 1), Obj("b", 2), Obj("d", 4)]

objArray1 += objArray2
objArray1 = Array(Set(objArray1))

But the objArray1 will contains all duplicated items.

I have check other questions like :
Removing Duplicates From Array of Custom Objects Swift .

Remove duplicate objects in an array .

However, in my case, I can't change Obj's superclass NSObject. The custom type must be a subclass of NSObject.

Question: Is there any elegant way to achieve merge two custom type array and remove duplicate custom type items

Yi Jiang
  • 3,938
  • 6
  • 30
  • 62
  • 3
    For an `NSObject` subclass, you need to override `isEqual(_:)` and `hash` (instead of overloading `==`), compare https://stackoverflow.com/q/33319959/2976878. – Hamish Mar 13 '18 at 00:04

2 Answers2

1
  var tempArray: [Obj] = []
  let removalArray = objArray1.filter { (someObj) -> Bool in
    if tempArray.isEmpty {
      tempArray.append(someObj)
      return true
    }
    if !tempArray.contains(where: { (anotherObj) -> Bool in
      return anotherObj.va2 == someObj.va2 && anotherObj.va1 == someObj.va1
    }) {
      tempArray.append(someObj)
      return true
    }
    return false
  }

I put this at the bottom before the set stuff.

jnblanchard
  • 1,182
  • 12
  • 12
0

I have resolved this issue based on @Hamish 's comment and the link .

class Obj: NSObject {
    var va1: String? = nil
    var va2: Int? = nil
    var value : Int

    init(_ v1: String,_ v2: Int){
        va1 = v1
        va2 = v2
        super.init()
    }


    override var hashValue : Int {
        var hashValueString = va1 ?? ""
        hashValueString += "\(va2 ?? 0)"
        return hashValueString.hashValue
    }

    override func isEqual(_ object: Any?) -> Bool {
        if let other = object as? Obj {
            return self.hashValue == other.hashValue
        } else {
            return false
        }
    }
}

var objArray1: [Obj] = [Obj("a", 1), Obj("b", 2), Obj("c", 3)]
var objArray2: [Obj] = [Obj("a", 1), Obj("b", 2), Obj("d", 4)]

objArray1 += objArray2
var objSet = Array(Set(objArray1))
Yi Jiang
  • 3,938
  • 6
  • 30
  • 62