удаление дубликатов из массива в цели c - PullRequest
12 голосов
/ 24 октября 2010

У меня есть массив с пользовательскими объектами. Каждый элемент массива имеет поле с именем «имя». Теперь я хочу удалить повторяющиеся записи на основе этого значения имени.

Как мне добиться этого?

Заранее спасибо.

Ответы [ 8 ]

28 голосов
/ 24 октября 2010

Я не знаю ни одного стандартного способа сделать это, предоставляемого фреймворками. Так что вам придется делать это в коде. Примерно так должно быть выполнимо:

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];
   }
}
9 голосов
/ 24 октября 2010

Возможно, вам придется написать этот метод фильтрации самостоятельно:

@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
7 голосов
/ 11 июля 2014

Я знаю, что это старый вопрос, но есть и другая возможность, в зависимости от того, что вам нужно.

Apple предоставляет способ сделать это - Операторы сбора ключей-значений .

Операторы объектов позволяют вам работать с коллекцией. В этом случае вы хотите:

@ distinctUnionOfObjects

Оператор @distinctUnionOfObjects возвращает массив, содержащий отдельные объекты в свойстве, указанном путем к ключу справа от оператора.

NSArray *distinctArray = [arrayWithDuplicates valueForKeyPath:@"@distinctUnionOfObjects.name"];

В вашем случае, однако, вы хотите весь объект. Так что вам нужно сделать в два раза: 1) Используйте @distinctUnionOfArrays вместо. Например. Если у вас были эти пользовательские объекты из других коллекций, используйте @distinctUnionOfArray.myCollectionOfObjects 2) Реализовать isEqual: для этих объектов, чтобы они возвращались, если их .name равны

2 голосов
/ 28 апреля 2014

Я собираюсь получить за это злобу ...

Вы можете конвертировать ваш массив в словарь.Не уверен, насколько это эффективно, зависит от реализации и вызова сравнения, но он использует хеш-карту.

//Get unique entries
NSArray *myArray = @[@"Hello", @"World", @"Hello"];
NSDictionary *uniq = [NSDictionary dictionaryWithObjects:myArray forKeys:myArray];
NSLog(@"%@", uniq.allKeys);

* Обратите внимание, это может изменить порядок вашего массива.

1 голос
/ 18 августа 2016

Это довольно просто в одну строку

NSArray *duplicateList = ... 

Если вам не важен порядок элементов, то (неупорядоченный)

NSArray *withoutDUP1 = [[NSSet setWithArray:duplicateList] allObjects];

Держите элементы в порядке тогда (упорядочено)

NSArray *withoutDUP2 = [[NSOrderedSet orderedSetWithArray:duplicateList] array];
1 голос
/ 23 августа 2013

Если вы беспокоитесь о заказе

NSArray * newArray =
        [[NSOrderedSet orderedSetWithArray:oldArray] array]; **// iOS 5.0 and later** 
1 голос
/ 02 мая 2013

Если вы хотите, чтобы ваши собственные подклассы NSObject считались равными, когда их имена равны, вы можете реализовать isEqual: и hash.Это позволит вам добавить объекты в NSSet / NSMutableSet (набор отдельных объектов).

Затем вы можете легко создать отсортированный NSArray, используя NSSet 's *Метод 1009 *.

MikeAsh написал довольно солидную статью о реализации пользовательского равенства: Пятница, вопросы и ответы 2010-06-18: Реализация равенства и хеширования

0 голосов
/ 16 февраля 2016

Реализуйте isEqual, чтобы сделать ваши объекты сопоставимыми:

@interface SomeObject (Equality)
@end

@implementation SomeObject (Equality)

- (BOOL)isEqual:(SomeObject*)other
{
    return self.hash == other.hash;
}

- (NSUInteger)hash
{
    return self.name;///your case
}

@end

Как использовать:

- (NSArray*)distinctObjectsFromArray:(NSArray*)array
{
    return [array valueForKeyPath:@"@distinctUnionOfObjects.self"];
}
...