是否有一个很好的解决方案来查找按号码重复的联系人
Is there a good solution for finding contacts duplicating by number
我尝试使用此代码获取重复项
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")
CNLabeledValue
对 Hashable
的实现没有考虑包含的值。每个实例都有一个唯一的哈希值。您应该改用 .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({ [=11=].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))")
}
}
我尝试使用此代码获取重复项
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")
CNLabeledValue
对 Hashable
的实现没有考虑包含的值。每个实例都有一个唯一的哈希值。您应该改用 .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({ [=11=].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))")
}
}