开发者

Remove all strings with duplicates in an NSArray

开发者 https://www.devze.com 2023-03-13 06:54 出处:网络
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.

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"


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. :-)


One liner : uniqueArray = [[NSSet setWithArray:duplicateArray] allObjects]; if you don't care about the ordering :D


A slightly different approach from Jacob's:

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

NSCountedSet *namesSet = [[NSCountedSet alloc] initWithArray:array];
NSMutableArray *namesArray = [[NSMutableArray alloc] initWithCapacity:[array count]];

[namesSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop){
    if ([namesSet countForObject:obj] == 1) {
        [namesArray addObject:obj];
    }
}];

And

NSLog(@"old: %@\nNew: %@", array, namesArray);

gives:

2011-06-16 18:10:32.783 SetTest[1756:903] old: (
    bob,
    frank,
    sarah,
    sarah,
    fred,
    corey,
    corey
)
New: (
    frank,
    fred,
    bob
)

Blocks are your friends! And since NSCountedSet is a subclass of NSSet you can use the block methods that are available there.


Here is the simplest approach to remove duplicate strings:

NSArray *array = [NSArray arrayWithObjects:@"bob", @"frank", @"sarah", @"sarah", @"fred", @"corey", @"corey", nil];
NSArray *distintStrings = [array valueForKeyPath:@"@distinctUnionOfObjects.self"];
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号