Swift: búsqueda de objects duplicates de CNContact en una matriz

Estoy intentando get duplicates CNContacts dentro de una Array :

Código:

  func fetchDuplicateContacts(){ self.didFinished_getDuplicateContacts = false; self.arr_duplicateContacts.removeAllObjects() NSLog("Start fetch duplicate", "") self.duplicateContactsCount = 0; for (var i: Int = 0; i < self.arr_allContacts.count; i++){ let contact1 = self.arr_allContacts[i] var hasDuplicate: Bool = false let arr_childs: NSMutableArray = NSMutableArray() for (var j: Int = 0; j < self.arr_allContacts.count; j++){ let contact2 = self.arr_allContacts[j] if(contact1 != contact2){ if CNContactFormatter.stringFromContact(contact1, style: .FullName) == CNContactFormatter.stringFromContact(contact2, style: .FullName){ if(self.checkIfContactsHaveSamePhones(contact1, contact2: contact2)){ print("Move on cuz duplicate: \(CNContactFormatter.stringFromContact(contact1, style: .FullName))") duplicateContactsCount += 1; arr_childs.addObject(NSDictionary(objects: [contact2, false], forKeys: ["object", "checked"])) hasDuplicate = true } } } } // This is for adding first contact to main array to be the first. It's important to be like this if hasDuplicate == true{ arr_childs.insertObject(NSDictionary(objects: [contact1, false], forKeys: ["object", "checked"]), atIndex: 0) var key: NSString? = CNContactFormatter.stringFromContact(contact1, style: .FullName) if key == nil { key = "no name \(i)" } arr_duplicateContacts.addObject([key! : arr_childs]) } } NSLog("End fetch duplicate w results \(self.duplicateContactsCount)", "") self.didFinished_getDuplicateContacts = true; dispatch_async(dispatch_get_main_queue(), { () -> Void in self.mytable.reloadData() }) } 

Recurro a través de la array , marque cada 2 contactos si tienen el mismo nombre y los mismos numbers y, si es true , agréguelos a una Array de NSDictionary (cuya key es el nombre del contacto y el object es un NSDictionary que contiene CNContact y un bool "checked"). .. Un poco desorderado, lo sé.

* El problema: obtendré duplicates dentro de la matriz principal *

Digamos que tengo Contact1["bob", "07100"] , Contact2["bob","07100"] . Cuando el bucle "j" verificará if Contact1 == Contact1 es verdadero y omite agregar el object a la matriz y luego comtesting Contact1 == Contact2 (falso y luego ve que Contact2 es un duplicado y anuncios a la matriz principal). Después de que i ++ hace lo mismo con Contact2 y este es el problema (intenta averiguar si hay 3 objects si no está claro).

Intenté solucionarlo asumiendo que los contactos duplicates son uno tras otro y usé ese i = j pero if Contact1 == Contact3 , Contact2 será omitido de la verificación

¿Alguna idea de cómo resolver este problema?

Pensé que propondría otra forma de lograr lo que intentas hacer aprovechando algunas de las funciones integradas de Swift. Una cosa a tener en count acerca de esta solución es que no ayudará a determinar cuál es el duplicado y cuál es el contacto que el usuario desea conservar. Esto es realmente un problema con su enfoque porque ¿qué sucede si ambos contactos tienen el mismo nombre pero un número diferente? Es por eso que en mi solución agrupo los duplicates y usted (o su usuario) puede decidir qué hacer.

  1. Obtenga una matriz de todos los nombres completos:

     let fullNames = self.arr_allContacts.map(CNContactFormatter.stringFromContact($0, style: .FullName)) 
  2. Haz que esa matriz sea única

     let uniqueArray = Array(Set(fullNames)) 
  3. Este es el paso que haré de manera diferente a lo que estás haciendo. Voy a build una matriz de matrices porque creo que llegará a donde quieres ir.

     var contactGroupedByUnique = [Array]() for (fullName in uniqueArray) { var group = self.arr_allContacts.filter { CNContactFormatter.stringFromContact($0, style: .FullName) == fullName } contactGroupedByUnique.append(group) } 
  4. Ahora puedes hacer lo siguiente:

     contactGroupedByUnique.count = //number of unique contact contactGroupedByUnique[index] = //number of duplicates of that contact 

No tengo time para probar el código, pero esto debería llevarlo hasta allí.