根据其键值之一删除 CNContact 数组
Posted
技术标签:
【中文标题】根据其键值之一删除 CNContact 数组【英文标题】:Removing a CNContact array based on one of its key value 【发布时间】:2016-11-04 10:08:26 【问题描述】:我是一个快速的新手,正在尝试使用联系人框架并遇到了一个问题:-
我有一个名为 contacts 的 CNContact
数组,键为 givenName
、familyName
和 phoneNumbers
。
我想从 contacts
String
类型的 names
我试过了:
for name in namesToRemove // 'name' is always in fullname format
contacts = contacts.filter () $0.givenName + " " + $0.familyName != name
但只有在同时指定 givenName
和 familyName
时才能进行删除。
另外,请记住,在 iPhone 设备上,某些联系人的全名仅在其“名字”或“姓氏”列中指定。
任何想法我该怎么做?非常感谢!
【问题讨论】:
【参考方案1】:您可以将contains
用于namesToRemove
数组作为对contacts
进行filter
操作的条件:
let filteredContacts = contacts.filter !namesToRemove.contains($0.givenName)
我们首先设置了一个CNContact
示例结构(因为您没有向我们提供最小的工作示例......)
/* example setup */
struct CNContact
let givenName: String
let familyName: String
let phoneNumbers: [String]
init(_ givenName: String, _ familyName: String,
_ phoneNumbers: [String])
self.givenName = givenName
self.familyName = familyName
self.phoneNumbers = phoneNumbers
let contacts = [CNContact("David", "Scott", ["123-567", "010-111"]),
CNContact("Lisa", "Rowling", ["134-521", "121-731"]),
CNContact("Brad", "Knight", ["621-141", "551-723"]),
CNContact("David", "Phelps", ["652-723", "718-888"]),
CNContact("Sarah", "Bright", ["166-720", "378-743"])]
示例用法:
/* example #1:
filter by removing any contacts that whose 'givenName' property
are contained in a list of given surnames to remove 'namesToRemove' */
let namesToRemove1 = ["David", "Sarah"]
let filteredContacts1 = contacts.filter !namesToRemove1.contains($0.givenName)
filteredContacts1.forEach
print($0.givenName, $0.familyName, $0.phoneNumbers.first ?? "none")
/* Lisa Rowling 134-521
Brad Knight 621-141 */
/* example #2:
filter by removing any contacts that whose 'givenName' and 'familyName'
properties are contained in a list of given full names to remove ('namesToRemove'),
where we know these full names are separated by exactly a single whitespace */
let namesToRemove2 = ["David Phelps", "Sarah Bright"]
let filteredContacts2 = contacts.filter
!namesToRemove2.contains($0.givenName + " " + $0.familyName)
filteredContacts2.forEach
print($0.givenName, $0.familyName, $0.phoneNumbers.first ?? "none")
/* David Scott 123-567
Lisa Rowling 134-521
Brad Knight 621-141 */
最后,根据您问题的后续更新,再举一个例子:
/* example #3:
filter by removing any contacts where at least one of the following
holds:
1. 'givenName' + " " + 'familyName' equals a name in 'namesToRemove',
2. 'givenName' by itself equals a name in 'namesToRemove',
3. 'familyName' by itself equals a name in 'namesToRemove', */
let contacts2 = [CNContact("David", "Scott", ["123-567", "010-111"]),
CNContact("Lisa", "Rowling", ["134-521", "121-731"]),
CNContact("", "Brad Knight", ["621-141", "551-723"]),
CNContact("David Phelps", "", ["652-723", "718-888"]),
CNContact("Sarah", "Bright", ["166-720", "378-743"])]
print(" ")
let namesToRemove3 = ["David Phelps", "Sarah Bright", "Brad Knight"]
let filteredContacts3 = contacts2.filter
!(namesToRemove3.contains($0.givenName + " " + $0.familyName) ||
namesToRemove3.contains($0.givenName) ||
namesToRemove3.contains($0.familyName))
filteredContacts3.forEach
print($0.givenName, $0.familyName, $0.phoneNumbers.first ?? "none")
/* David Scott 123-567
Lisa Rowling 134-521 */
【讨论】:
这很棒。但是,如果我也想包含 key familyName 怎么办?考虑到本地电话簿中保存的联系信息有时仅使用“名字”列作为全名?可以安全地假设 namesToRemove 中的元素都使用全名(givenName + familyName) @ArezWong 我不确定我是否完全遵循您想要实现的目标。您能否用contact
数组、namesToRemove
数组的实际示例更新您的问题,以及过滤后结果数组的外观?确保您的示例考虑到您尝试指定的所有用例。
试过这个let filteredContacts = contacts.filter !namesToRemove.contains($0.givenName + " " + $0.familyName)
。如果联系人的全名已完成且已将 givenName 和 familyName 组合在一起,则可以使用。
@ArezWong 另外,请避免问题的后续更新,使其随着每个答案的出现而增长。我将包含一个最后的更新,但这现在已经发展成为“考虑为我编写此应用程序代码”,而不是为您指明正确的方向 w.r.t.过滤的工作原理。
@ArezWong 包含最后一个示例,该示例通过检查来过滤namesToRemove
数组:1. 全名(来自namesToRemove
)匹配与合并givenName + " " + familyName
,2. 全名(来自@987654336 @) 匹配与givenName
,3. 全名(来自namesToRemove
)匹配与familyName
。以上是关于根据其键值之一删除 CNContact 数组的主要内容,如果未能解决你的问题,请参考以下文章