views:

71

answers:

2

I have an array with custom objects. Each array item has a field named "name". Now I want to remove duplicate entries based on this name value.

How should I go about achieving this.

Thanks in advance.

+2  A: 

You might have to actually write this filtering method yourself:

@interface NSArray (CustomFiltering)
@end

@implementation NSArray (CustomFiltering) 

- (NSArray *) filterObjectsByKey:(NSString *) key {
   NSMutableSet *tempValues = [[NSMutableSet alloc] init];
   NSMutableArray *ret = [NSMutableArray array];
   for(id obj in self) {
       if(! [tempValues containsObject:[obj valueForKey:key]]) {
            [tempValues addObject:[obj valueForKey:key]];
            [ret addObject:obj];
       }
   }
   [tempValues release];
   return ret;
}

@end
Jacob Relkin
its not a string array its a custom object array.... with a string name as the property... I want to filter based in this name property
Asad Khan
Would the downvoter care to comment?
Jacob Relkin
@Jacob: Wrote my answer just as you edited yours. You really should use an `NSMutableSet` instead of a `NSMutableArray` for lookups, the performance boost from a hash lookup is quite allot better than a linear search.
PeyloW
@PeyloW, Thanks for the advice!
Jacob Relkin
A couple of comments. First, you should just use `[NSMutableSet set]` instead of alloc/init+release. Second, you should use `-member:` instead of `-containsObject:`. `-containsObject:` is documented as returning whether the given object is present in the set, without defining "present". It is reasonable to assume it uses pointer equality. `-member:` is documented as using `-isEqual:`, which is what you actually want to test with.
Kevin Ballard
Asad Khan
@Kevin, -containsObject: looks for membership the same way as -member: does. The only diff is returning BOOL versus the object itself.
Firoze Lafeer
@Kevin, I used `alloc/init` because I didn't want the set to be sitting around in the autorelease pool. The code only actually *needs* the set to be around while the loop is executing, so this way it can be released from memory at the earliest possible time.
Jacob Relkin
+1  A: 

I do not know of any standard way to to do this provided by the frameworks. So you will have to do it in code. Something like this should be doable:

NSArray* originalArray = ... // However you fetch it
NSMutableSet* existingNames = [NSMutableSet set];
NSMutableArray* filteredArray = [NSMutableArray array];
for (id object in originalArray) {
   if (![existingNames containsObject:[object name]]) {
      [existingNames addObject:[object name]];
      [filteredArray addObject:object];
   }
}
PeyloW
Thanks PeyloW your answer was right on spot... thumbs up... I wish you best of luck in your endeavors....
Asad Khan