根据其键值之一删除 CNContact 数组

Posted

技术标签:

【中文标题】根据其键值之一删除 CNContact 数组【英文标题】:Removing a CNContact array based on one of its key value 【发布时间】:2016-11-04 10:08:26 【问题描述】:

我是一个快速的新手,正在尝试使用联系人框架并遇到了一个问题:-

我有一个名为 contactsCNContact 数组,键为 givenNamefamilyNamephoneNumbers。 我想从 contacts

数组中过滤掉某些定义为 String 类型的 names

我试过了:

for name in namesToRemove  // 'name' is always in fullname format
    contacts = contacts.filter ()  $0.givenName + " " + $0.familyName != name 

但只有在同时指定 givenNamefamilyName 时才能进行删除。

另外,请记住,在 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 数组的主要内容,如果未能解决你的问题,请参考以下文章

javascript 根据键值在数组中查找和删除对象

Laravel - 根据键值删除数组内的对象 - array_filter

Redis之字典

数组随机排序 shuffle

基于键值取消设置数组[关闭]

Ch5 关联式容器(中)