【问题标题】:NSDictionary with duplicated objects checked检查重复对象的 NSDictionary
【发布时间】:2016-02-23 22:30:20
【问题描述】:

我正在寻找一个作为键对象的结构,如NSDictionary,但也有其计算重复对象并通过键定义这些重复的方法。我尝试NSCountedSet,但这个类没有key-object。 Foundation 上是否有任何可用的结构类型,或者我必须自己构建?

.....详细更新问题:

我查找重复联系人的结构,可以在他们的电子邮件中找到,因为这是唯一的,尽管他们的名字不同,但全名可能不同,例如:

NSMutableDictionary* listContacts = [[NSMutableDictionary alloc] init];
[listContact setObject:@”john.smith@email.com” forKey:@”john Smith”];
[listContact setObject:@”lara.croft@email.com” forKey:@”lara Croft”];
[listContact setObject:@”john.smith@email.com” forKey:@” Smith John”];
[listContact setObject:@”james.bond@email.com” forKey:@”James bond”];

NSDictionary 的 count 方法只计算它的元素个数。我知道@“john Smith”和@“Smith John”是一个,因为他的电子邮件是一样的。但是 NSDictionary 没有在对象上查找重复项的方法:@“john.smith@email.com”。我尝试将 NSCountedSet 设置为:

NSMutableArray* email = @[@”john.smith@email.com”, @”lara.croft@email.com”, @”john.smith@email.com”, @”james.bond@email.com”];
NSCountedSet* duplicateContacts = [[NSCountedSet alloc] initWithArray:email];
for (NSNumber *num in duplicateContacts)
{
    if ([duplicateContacts countForObject:num]>1)
       {
NSLog(@"duplicated %lu time of %@",[findDuplicate countForObject:num],num);
      }
}

它只找到了重复的电子邮件,找不到它的相关名称。

如果我尝试 NSDictionary 的结构为:

NSMutableDictionary* listContacts = [[NSMutableDictionary alloc] init];
[listContact setObject: @”john Smith”  forKey: @”john.smith@email.com”];
[listContact setObject: @”lara Croft”   forKey: @”lara.croft@email.com”];
[listContact setObject: @” Smith John”  forKey: @”john.smith@email.com”];
[listContact setObject: @”James bond”  forKey: @”james.bond@email.com”];

NSDictionary 会静默删除添加的重复键,只剩下这个 NSDictionary 的结果:

Object: @”lara Croft” Key: @”lara.croft@email.com”;
Object: @” Smith John” Key: @”john.smith@email.com”;
Object: @”James bond” Key: @”james.bond@email.com”;

对象:@“john Smith” 密钥:@“john.smith@email.com”已被删除,因为密钥重复:@”john.smith@email.com”

【问题讨论】:

  • 请举例说明你想在数据结构中存储什么以及你想执行什么操作!?
  • 不确定你在问什么。 NSDictionary 也有方法count。这不是你要找的吗?
  • 我为你们的cmets更新了我的问题,我不知道如何在我的评论中添加代码和长回复。
  • 你想对重复的条目做什么?您不想像上一个示例(键:电子邮件,对象:名称)那样简单地删除它们吗?

标签: ios objective-c nsdictionary key-value


【解决方案1】:

我只想创建一个数组字典。键是电子邮件地址,值是联系人/姓名数组。每个键的计数只是其值的计数(数组中元素的数量)。

您可以使用以下算法构造它:

NSArray *contacts = ...;
NSMutableDictionary *keyedEmails = [NSMutableDictionary dictionary];

for (Contact *contact in contacts) {
    NSMutableArray *contactsForEmail = keyedEmails[contact.email];
    if (contactsForEmail = nil) {
        contactsForEmail = [NSMutableArray array];
        keyedEmails[contact.email] = contactsForEmail;
    }

    [contactsForEmail addObject:contact];
}

您甚至可以通过简单的语法获取任何电子邮件的计数:

NSUInteger countForEmail = keyedEmails[email].count;

【讨论】:

    【解决方案2】:

    我认为您应该在此过程的早期检查重复的电子邮件,即在创建或添加此信息时。

    这很啰嗦,但我认为它最能说明如何使用当前数据结构实现您的要求。

    NSMutableArray *names = [[NSMutableArray alloc] initWithObjects:
                             @"John Smith",
                             @"Lara Croft",
                             @"Smith John",
                             @"James Bond", nil];
    
    NSMutableArray *emails = [[NSMutableArray alloc] initWithObjects:
                              @"john.smith@email.com",
                              @"lara.croft@email.com",
                              @"john.smith@email.com",
                              @"james.bond@email.com", nil];
    
    
    NSMutableArray *nestedArray = [[NSMutableArray alloc] initWithObjects:names,emails, nil];
    
    NSMutableArray *tmp = [[NSMutableArray alloc] init];
    NSMutableArray *foo = [[NSMutableArray alloc] init];
    NSMutableArray *bar = [[NSMutableArray alloc] init];
    
    int count = 0;
    
    for (NSString *string in [nestedArray objectAtIndex:1]) {
    
        if ([tmp containsObject:string]) {
    
            //object already exists in our array
    
            [bar addObject:string];
            [foo addObject:[[nestedArray objectAtIndex:0] objectAtIndex:count]];
            NSLog(@"Adding key to bar: %@ \n foo: %@",bar,foo);
    
            // use count to access the name associated with the email [[nestedArray objectAtIndex:0] objectAtIndex:count];
    
        }else{
    
            //add object as it doesnt exist in our array
    
            [tmp addObject:string];
    
            NSLog(@"Adding key to foo: %@",tmp);
    
        }
    
        count++;
    }
    
    NSLog(@"foo: %@ \n bar: %@",foo,bar);
    

    我仍然建议您创建一个 NSObject 来优化您的数据管理。

    bar 将为您提供重复的密钥。

    foo 会给你你的名字。

    【讨论】:

    • 谢谢@Nicholas,这是一个很好的建议。虽然我认为 NSDictionary 这样做检查重复并通知作为选项参数更好,而不是静默删除。
    • 不想知道重复邮件的每个联系人吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-27
    • 1970-01-01
    • 1970-01-01
    • 2018-12-23
    • 2016-04-01
    相关资源
    最近更新 更多