是否有一个很好的解决方案来查找按号码重复的联系人

Posted

技术标签:

【中文标题】是否有一个很好的解决方案来查找按号码重复的联系人【英文标题】:Is there a good solution for finding contacts duplicating by number 【发布时间】:2022-01-06 05:20:47 【问题描述】:

我尝试使用此代码获取重复项

 var contactsByNumber = [CNLabeledValue<CNPhoneNumber>:[CNContact]]()
                
 try self.store.enumerateContacts(with: fetchRequest)  [weak self] contact, stopPointerIfYouWantToStopEnumeration in
                         
                    //Check contact for matching number with other contacts
                    for contactNumber in contact.phoneNumbers 
                        var contactsForNumber = contactsByNumber[contactNumber,default: []]
                        contactsForNumber.append(contact)
                        contactsByNumber[contactNumber] = contactsForNumber
                        print("Contacts count for number \(contactNumber.value.stringValue): \(contactsByNumber[contactNumber]!.count)")
                        print("Owner \(formatter.string(from: contact))")
                    
 

我还创建了两个具有相同号码的联系人,但它打印出控制台中每个号码只有一个联系人:

Contacts count for number (408) 555-3514: 1
Owner Optional("Daniel Higgins Jr.")
Contacts count for number 888-555-5512: 1
Owner Optional("John Appleseed")
Contacts count for number 888-555-1212: 1
Owner Optional("John Appleseed")
Contacts count for number 555-522-8243: 1
Owner Optional("Anna Haro")
Contacts count for number (555) 766-4823: 1
Owner Optional("Hank M. Zakroff")
Contacts count for number (707) 555-1854: 1
Owner Optional("Hank M. Zakroff")
Contacts count for number 555-610-6679: 1
Owner Optional("David Taylor")
Contacts count for number +7 (898) 222-55-22: 1
Owner Optional("FirstMatchingNumber")
Contacts count for number +7 (898) 222-55-22: 1
Owner Optional("SecondMatchingNumber")

【问题讨论】:

【参考方案1】:

CNLabeledValueHashable 的实现没有考虑包含的值。每个实例都有一个唯一的哈希值。你应该改用.value,它会给你一个CNPhoneNumber,它似乎在散列时考虑了这个值,这意味着你的条目将被分配给同一个字典键:

let number = CNLabeledValue<CNPhoneNumber>(label: nil, value: CNPhoneNumber(stringValue: "123454"))
let number2 = CNLabeledValue<CNPhoneNumber>(label: nil, value: CNPhoneNumber(stringValue: "123454"))
print(number.hashValue == number2.hashValue) // false
print(number.value.hashValue == number2.value.hashValue) //true

所以你的代码应该是:

var contactsByNumber = [CNPhoneNumber:[CNContact]]()
                
try self.store.enumerateContacts(with: fetchRequest)  [weak self] contact, stopPointerIfYouWantToStopEnumeration in
                         
    //Check contact for matching number with other contacts
    for contactNumber in contact.phoneNumbers.map( $0.value ) 
        var contactsForNumber = contactsByNumber[contactNumber,default: []]
        contactsForNumber.append(contact)
        contactsByNumber[contactNumber] = contactsForNumber
        print("Contacts count for number \(contactNumber.stringValue): \(contactsByNumber[contactNumber]!.count)")
                        print("Owner \(formatter.string(from: contact))")
    

【讨论】:

以上是关于是否有一个很好的解决方案来查找按号码重复的联系人的主要内容,如果未能解决你的问题,请参考以下文章

如何很好地构建具有重复元素的表单

使用 sqlite 查找连续重复的数量

Android:联系人列表有重复的名字

是否可以在移动 Safari 中检测邮政地址,以便将其添加到联系人中?

两张excel表格如何找出相同的身份证号码?【急】

根据电话号码添加原始联系人时联系人重复