2017-10-10 4 views
0

J'écris un composant pour mettre en cache des instances de classes. Les classes ne sont pas en soi Comparable, Hashable ou Equatable. Si c'était le cas, la sémantique des opérations respectives ne servirait pas nécessairement nos objectifs, alors disons que nous ne pouvons pas utiliser ces protocoles.Supprimer les instances de classe en double en fonction de l'identité de l'objet

Les objets peuvent être mis en cache w.r.t. plusieurs clés. Donc, lorsque vous demandez au cache une liste de tous les objets mis en cache, j'ai besoin de supprimer les doublons de l'ensemble de valeurs du dictionnaire sous-jacent - en ce qui concerne identité de l'objet.

De toute évidence, cela fait le travail:

var result: [C] = [] 
for c in dict.values { 
    if !result.contains(where: { (rc: C) in rc === c }) { 
     result.append(c) 
    } 
} 
return result 

Cependant, cela a un comportement d'exécution du second degré. Comparé au comportement linéarithmique ou linéaire attendu qui est facile à obtenir en utilisant les protocoles mentionnés ci-dessus (en utilisant des implémentations d'ensemble), ceci est mauvais. Alors, comment peut-on éliminer efficacement les doublons avec le

identité d'objet d'une collection Swift?

Répondre

0

Nous pouvons envelopper nos objets dans quelque chose qui est Hashable et Comparable:

struct ClassWrap<T: AnyObject>: Hashable, Comparable { 
    var value: T 

    var hashValue: Int { 
     return ObjectIdentifier(self.value).hashValue 
    } 

    static func ==(lhs: ClassWrap, rhs: ClassWrap) -> Bool { 
     return lhs.value === rhs.value 
    } 

    static func <(lhs: ClassWrap<T>, rhs: ClassWrap<T>) -> Bool { 
     return ObjectIdentifier(lhs.value) < ObjectIdentifier(rhs.value) 
    } 
} 

Maintenant, toute mise en œuvre Set régulière ou autre opération fying unique, devrait faire le travail.