在NSMutableArray中查找重复的对象属性

时间:2014-07-29 19:33:49

标签: objective-c cocoa-touch cocoa search nsarray

我有一个班级Person,其中有一个属性firstname。然后会将Person个对象添加到另一个类中的allPeople NSMutableArray

 @interface class1 : NSObject

@property (nonatomic, strong) NSMutableArray *allPeople;

然后在'class1'中有一个方法,它确定数组中firstname对象的Person属性是否与数组中的另一个firstname属性相同。

这就是我被困住的地方,基本上只有五个人需要进行比较。

我想做的是: -

-(BOOL)samefirstname{
    //i don't want to tamper with the original allPeople array so i make a mutable copy
    NSMutableArray *tempallpeople = [self.allPeople mutableCopy];
    for every person object in [tempallpeople]{
    if(person1.firstname == person2.firstname || or person1.firstname == person3.firstname || person1.firstname == person4.firstname || or person1.firstname == person5.firstname{
       return YES;   
     }else if (person2.firstname ect ect.

如果有人能够对我的问题有所了解,那就太棒了。

6 个答案:

答案 0 :(得分:4)

您可以使用-[NSArray valueForKey:]获取数组中每个对象的特定属性的值。 NSSet是一个包含一组没有重复项的对象的集合。如果您从名字数组创建一个集合并且它们的大小相同,那么您就没有重复项。

- (BOOL)haveDuplicateFirstNames
{
    NSArray * firstNames = [[self allPeople] valueForKey:@"firstname"];
    return [firstNames count] != [[NSSet setWithArray:firstNames] count];
}

答案 1 :(得分:3)

将名称提取到一个集合中,如果集合的计数与人数不同,则表示名称重复。

请注意,这将是完全匹配(案例和变音符号敏感)并且不会告诉您副本是哪个。

NSArray *names = [self.allPeople valueForKey:@"firstname"];
NSSet *filteredNames = [NSSet setWithArray:names];

return (names.count != filteredNames.count);

答案 2 :(得分:1)

目前尚不清楚是否要查找重复的名称,或者是否要检查阵列上是否已有名称,所以这两者都是:

-(BOOL)hasName:(NSString*)name{

    if([self.allPeople indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {

        if([[obj firstname] isEqualToString:name]){
            *stop = YES;
            return YES;
        }

        return NO;

    }] != NSNotFound){
        return YES; // user with that name already exists
    }
    else{
        return NO; // name does not exists
    }
}

-(BOOL)hasDuplicateName{

    for(id first_object in self.allPeople){

        if([self.allPeople indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {

            if([[obj firstname] isEqualToString:[first_object firstname]] && obj != first_object){
                *stop = YES;
                return YES;
            }

            return NO;

        }] != NSNotFound){
           return YES; // user with that name already exists
        }
        else{
           return NO; // name does not exists
        }

    }
}

将“id”类型更改为Person类,这应该有效。

答案 3 :(得分:1)

这实际上更多的是评论而不是答案,但是如果您需要在多个地方进行同样的检查,这里可以进一步概括@JoshCaswell和@Wain所描述的功能。首先,在NSArray上的类别中添加方法以执行重复测试:

@implementation NSArray (XYZAdditions)

- (BOOL)xyz_hasDuplicateValuesForKey:(NSString *)key
{
    NSArray *allValues = [self valueForKey:key];
    NSSet *uniqueValues = [NSSet setWithArray:allValues];

    return allValues.count > uniqueValues.count;
}

@end

然后,只要您想检查任何给定数组中对象的重复属性,就可以调用该方法。例如下面的代码......

NSArray *people = @[ [[Person alloc] initWithFirstName:@"Fred" lastName:@"Smith" age:22],
                     [[Person alloc] initWithFirstName:@"Sue" lastName:@"Smith" age:28],
                     [[Person alloc] initWithFirstName:@"Bill" lastName:@"Brown" age:28]];

NSLog(@"Duplicate first names? %@", [people xyz_hasDuplicateValuesForKey:@"firstName"] ? @"Yes" : @"No");
NSLog(@"Duplicate last names? %@", [people xyz_hasDuplicateValuesForKey:@"lastName"] ? @"Yes" : @"No");
NSLog(@"Duplicate ages? %@", [people xyz_hasDuplicateValuesForKey:@"age"] ? @"Yes" : @"No");

...产生以下输出:

2014-07-29 16:14:56.031 xctest[4588:303] Duplicate first names? No
2014-07-29 16:14:56.031 xctest[4588:303] Duplicate last names? Yes
2014-07-29 16:14:56.031 xctest[4588:303] Duplicate ages? Yes

答案 4 :(得分:0)

您想知道数组是否包含两个具有相同名称的Person个对象,对吗?

这样做:

BOOL contains = NO;

for (int i = 0; i < [self.allPeople count]; ++i) {
  for (int j = 0; j < i; ++j) {
    Person *p1 = (Person *) self.allPeople[i];
    Person *p2 = (Person *) self.allPeople[j];

    if ([p1.name isEqualToString:p2.name]) {
      contains = YES;
      break;
    }
  } 

  if (contains) { break; }
}

答案 5 :(得分:0)

BOOL firstNameIsUnique = YES;
for (Person *person1 in allPersons) {
    for (Person *person2 in allPersons) {
        if (person1 != person2 && [person1.firstName isEqualToString:person2.firstName]) {
            firstNameIsUnique = NO;
            break;
        }
    }
    if (!firstNameIsUnique) break;
}

通过数组枚举,对于数组中的每个人,您再次枚举数组以查看名字是否匹配。如果找到匹配项,则设置BOOL并且代码从枚举中突破。

请注意,您无法使用==比较两个对象。阅读有关解释的指针。

另请注意,这不是最正确的答案。建议使用套装的人更好。