У меня есть следующий код в Playgraound, который работает не так, как я хочу.

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))

Но objArray1 будет содержать все повторяющиеся элементы.

У меня есть другие вопросы, например:
Удаление дубликатов из массива настраиваемых объектов Swift.

Удалите повторяющиеся объекты в массиве.

Однако в моем случае я не могу изменить суперкласс Obj NSObject. Пользовательский тип должен быть подклассом NSObject.

Вопрос: Есть ли какой-нибудь элегантный способ добиться слияния двух массивов настраиваемого типа и удаления повторяющихся элементов настраиваемого типа

1
Yi Jiang 13 Мар 2018 в 03:00

2 ответа

Лучший ответ

Я решил эту проблему на основе комментария @Hamish и ссылки .

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))
0
Yi Jiang 13 Мар 2018 в 00:42
  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
  }

Я поставил это внизу перед набором вещей.

1
jnblanchard 13 Мар 2018 в 00:53