Removendo duplicatas do NSMutableArray

Eu tenho esse problema com a remoção de objects duplicados de uma matriz. Eu tentei estes já:

noDuplicates = _personalHistory.personalHistory; for (int i=[noDuplicates count]-1; i>0; i--) { if ([noDuplicates indexOfObject: [noDuplicates objectAtIndex: i]]<i) [noDuplicates removeObjectAtIndex: i]; } for (PersonalHistory_artikels *e in _personalHistory.personalHistory) { if (![noDuplicates containsObject:e]) { NSLog(@"Dubplicates"); [noDuplicates addObject:e]; } } for (i=0; i<_personalHistory.personalHistory.count; i++) { PersonalHistory_artikels *test = [_personalHistory.personalHistory objectAtIndex:i]; for (j=0; j<_personalHistory.personalHistory.count; j++) { PersonalHistory_artikels *test2 = [_personalHistory.personalHistory objectAtIndex:j]; if (! [test.nieuwsTITLE_personal isEqual:test2.nieuwsTITLE_personal]) { NSLog(@"Add test = %@", test.nieuwsTITLE_personal); [noDuplicates addObject:test]; } } } 

Mas nenhum dos itens acima me deu a matriz correta. O último foi o melhor, mas ainda mostrava valores duplicados. Alguém pode me ajudar com este problema? Muito obrigado.

Basta converter a matriz para um NSSet e NSSet -versa. Um conjunto não pode ter duplicatas por design.

EDITAR:

Observe que um conjunto não tem uma ordem de sorting. Portanto, você pode ir mais barato e renunciar ao pedido, ou ir para uma operação um pouco mais cara, mas manter o pedido.

 NSArray *hasDuplicates = /* (...) */; NSArray *noDuplicates = [[NSSet setWithArray: hasDuplicates] allObjects]; 

No OS X 10.7 e iOS 5.0 e posterior:

 newArray = [[NSOrderedSet orderedSetWithArray:oldArray] array]; 

Se você quiser manter a ordem, você pode fazer algo assim

 @interface NSArray (OrderedDuplicateElimination) - (NSArray *)arrayByEliminatingDuplicatesMaintainingOrder { NSMutableSet *addedObjects = [NSMutableSet set]; NSMutableArray *result = [NSMutableArray array]; for (id obj in self) { if (![addedObjects containsObject:obj]) { [result addObject:obj]; [addedObjects addObject:obj]; } } return result; } @end 

Esta solução tem menor complexidade computacional do que a maioria dos outros até agora sugeridos; para um array com N elementos dos quais M é único, deve ter a pior complexidade O (N log M), ao invés de O (N ^ 2). No entanto, as soluções mais simples podem ser mais rápidas para matrizes curtas, pois esse método tem alguma sobrecarga adicional.

Naturalmente, ele depende de seus -isEqual: e -hash sendo implementados corretamente.

Como sobre esta categoria?

 @implementation NSArray (Unique) - (NSArray*) arrayByDroppingDuplicates { NSMutableArray *tmp = [NSMutableArray array]; for (id item in self) if (![tmp containsObject:item]) [tmp addObject:item]; return [NSArray arrayWithArray:tmp]; } @end 

Você pode usá-lo assim:

 NSArray *items = [NSArray arrayWithObjects:@"foo", @"bar", @"foo", nil]; NSArray *unique = [items arrayByDroppingDuplicates]; // [@"foo", @"bar"] 

Eu acho que o seu problema está em como você define a igualdade de seus objects PersonalHistory_artikels .

Independentemente do algoritmo usado para remover duplicatas em uma matriz, certifique-se de fornecer as -isEqual: adequadas do -isEqual: e -hash . Veja a documentação da Apple para esses dois methods, particularmente este parágrafo:

Se dois objects são iguais (conforme determinado pelo método isEqual:), eles devem ter o mesmo valor de hash. Este último ponto é particularmente importante se você definir hash em uma subclass e pretender colocar instâncias dessa subclass em uma coleção.

Se um object mutável for adicionado a uma coleção que usa valores de hash para determinar a posição do object na coleção, o valor retornado pelo método de hash do object não deve ser alterado enquanto o object estiver na coleção. Portanto, o método hash não deve confiar em qualquer informação de estado interno do object ou você deve certificar-se de que as informações de estado interno do object não sejam alteradas enquanto o object estiver na coleção. Assim, por exemplo, um dictionary mutável pode ser colocado em uma tabela de hash, mas você não deve alterá-lo enquanto estiver lá. (Observe que pode ser difícil saber se um determinado object está ou não em uma coleção.)

Espero que isto ajude.

 NSArray *copy = [mutableArray copy]; NSInteger index = [copy count] - 1; for (id object in [copy reverseObjectEnumerator]) { if ([mutableArray indexOfObject:object inRange:NSMakeRange(0, index)] != NSNotFound) { [mutableArray removeObjectAtIndex:index]; } index--; } [copy release]; 

Melhor maneira de remover o elemento duplicado da matriz:

 uniquearray = [[NSSet setWithArray:yourarray] allObjects]; 

Não há necessidade de criar o NSSet ou qualquer outra coisa. Tente isso

 noDuplicates = [orgArray valueForKeyPath:@"@distinctUnionOfObjects.self"]; 

Para matriz que contém objects personalizados:

  NSArray *arrUnique = [_pSessionArr valueForKeyPath:@"@distinctUnionOfObjects.self.title"]; [_pSessionArr removeObjectsInRange:NSMakeRange(arrUnique.count, _pSessionArr.count-arrUnique.count )]; 

PS: _pSessionArr é o nome da matriz mutável que contém um object de class personalizado que possui uma propriedade chamada title.