Удалите все строки с дубликатами в NSArray - PullRequest
12 голосов
/ 16 июня 2011

Я пытаюсь выяснить, как реализовать это в Objective-C.

Я хочу удалить строки в NSArray, которые появляются в массиве более одного раза.

В конце я хочу получить массив, в котором есть только уникальные строки в массиве (это означает, что удаляются не только дубликаты, но и исходная строка, которая соответствует дубликатам.)

Например, если бы у вас был следующий массив:

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

Я бы хотел, чтобы новый массив выглядел так:

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

Ответы [ 4 ]

24 голосов
/ 16 июня 2011

Используйте 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 предложил добавить в NSCountedSet метод с именем -objectsWithCount:,, который я реализовал здесь:

@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

Как только это будет сделано, все, что вам нужно, это одна строка :

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

Кстати, это не зависит от типа, поэтому будет работать с любым объектом Objective-C. : -)

9 голосов
/ 11 августа 2011

Один вкладыш: uniqueArray = [[NSSet setWithArray:duplicateArray] allObjects];, если вы не заботитесь о заказе: D

3 голосов
/ 16 июня 2011

Немного отличается от Иакова :

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];
    }
}];

А

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

дает:

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

Блоки твои друзья! А поскольку NSCountedSet является подклассом NSSet, вы можете использовать доступные там блочные методы.

2 голосов
/ 21 мая 2016

Вот самый простой подход для удаления дублирующихся строк:

NSArray *array = [NSArray arrayWithObjects:@"bob", @"frank", @"sarah", @"sarah", @"fred", @"corey", @"corey", nil];
NSArray *distintStrings = [array valueForKeyPath:@"@distinctUnionOfObjects.self"];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...