user801903 user801903 - 6 months ago 14
Objective-C Question

Remove all strings with duplicates in an NSArray

I am trying to figure out how to implement this in Objective-C.

I want to remove the strings in an

NSArray
that have appear more than once in the array.

At the end I want to have an array that only has the unique lines in an array (meaning that not just the duplicates are deleted but also the original string that matches the duplicates.)

For example if you had the following array:

NSArray *array = [NSArray arrayWithObjects:@"bob", @"frank", @"sarah", @"sarah", @"fred", @"corey", @"corey", nil];


I would want the new array to look like this:

@"bob", @"frank", @"fred"

Answer

Use an NSCountedSet:

NSCountedSet *countedSet = [NSCountedSet setWithArray:yourArray];
NSMutableArray *finalArray = [NSMutableArray arrayWithCapacity:[yourArray count]];

for(id obj in countedSet) {
   if([countedSet countForObject:obj] == 1) {
      [finalArray addObject:obj];
   }
}

@Caleb suggested adding a method to NSCountedSet called -objectsWithCount:,, which I've implemented here:

@interface NSCountedSet (JRCountedSetAdditions)

- (NSArray *) objectsWithCount:(NSUInteger) count;

@end

@implementation NSCountedSet (JRCountedSetAdditions) 

- (NSArray *) objectsWithCount:(NSUInteger) count {
   NSMutableArray *array = [NSMutableArray array];
   for(id obj in self) {
      if([self countForObject:obj] == count) {
        [array addObject:obj];
      }  
   }
   return [array copy];
}

@end

Once that's done, all you need is one line:

NSArray *finalArray = [[NSCountedSet setWithArray:yourArray] objectsWithCount:1];

By the way, this is type-agnostic, so this will work with any Objective-C object. :-)