Mam tablicę z niestandardowymi obiektami. Każdy element tablicy ma pole o nazwie "nazwa". Teraz chcę usunąć zduplikowane wpisy na podstawie tej wartości nazwy.usuwanie duplikatów z tablicy w obiekcie c
Jak mam to osiągnąć?
Z góry dziękuję.
Mam tablicę z niestandardowymi obiektami. Każdy element tablicy ma pole o nazwie "nazwa". Teraz chcę usunąć zduplikowane wpisy na podstawie tej wartości nazwy.usuwanie duplikatów z tablicy w obiekcie c
Jak mam to osiągnąć?
Z góry dziękuję.
Można mieć faktycznie napisać tę metodę filtrowania siebie:
@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
to nie jest tablica ciągów jej niestandardowa tablica obiektów .... z nazwą ciągu jako właściwością ... Chcę filtrować oparta na tej nazwie właściwość –
Czy ta ostatnia uwaga będzie komentować? –
@Jacob: Napisałem odpowiedź tak, jak edytowałeś. Naprawdę powinieneś użyć 'NSMutableSet' zamiast' NSMutableArray' dla wyszukiwań, zwiększenie wydajności z hash lookup jest dużo lepsze niż wyszukiwanie liniowe. – PeyloW
nie wiem z dowolnym standardowym sposobem do tego dostarczone przez ram zrobić. Będziesz musiał to zrobić w kodzie. Coś takiego powinno być wykonalne:
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];
}
}
Dzięki PeyloW Twoja odpowiedź była na miejscu ... Kciuk w górę ... Życzę powodzenia w Twoich staraniach .... –
Nie powinien to być [object objectForKey: @ "name"]; w tej pętli? –
bez Skeatera. To dla NSDictionary. –
Jeśli chcesz niestandardowych NSObject podklasy należy uznać za równe, gdy ich nazwy są równe można wdrożyć isEqual:
i hash
. Umożliwi to dodanie obiektów do obiektu NSSet
/NSMutableSet
(zestawu odrębnych obiektów).
Następnie można łatwo utworzyć posortowane NSArray
przy użyciu metody NSSet
's sortedArrayUsingDescriptors:
.
MikeAsh napisał całkiem solidny kawałek o wdrożenie niestandardowych równości: Friday Q&A 2010-06-18: Implementing Equality and Hashing
Jeśli martwisz się o kolejności
NSArray * newArray =
[[NSOrderedSet orderedSetWithArray:oldArray] array]; **// iOS 5.0 and later**
Zamierzam dostać flak dla tego ...
Możesz przekonwertować tablicę na słownik. Nie wiem, na ile jest to efektywne, zależy od implementacji i wywołania porównania, ale korzysta z mapy skrótów.
//Get unique entries
NSArray *myArray = @[@"Hello", @"World", @"Hello"];
NSDictionary *uniq = [NSDictionary dictionaryWithObjects:myArray forKeys:myArray];
NSLog(@"%@", uniq.allKeys);
Hehehehe KOCHAM to! –
Edycja: dobrze spędziłem ostatnie 15 minut naprawiając błąd w moim kodzie. Użycie tej metody NSDictionary NIE zachowuje ORDERU twojej tablicy. Wszystkie moje przedmioty były porozrzucane. To właśnie dostaję za używanie hacky wordk-arounds gdzie OP poprzedza "Mam zamiar dostać flaka za to ..." lol –
Wiem, że to stare pytanie, ale tutaj jest inna możliwość, w zależności od potrzeb.
Apple zapewnia sposób na zrobienie tego - Key-Value Coding Collection Operators.
Operatory obiektów umożliwiają działanie w kolekcji. W tym przypadku, chcesz:
@distinctUnionOfObjects
Operator @distinctUnionOfObjects zwraca tablicę zawierającą różne obiekty w nieruchomości określonej przez ścieżkę klucza po prawej stronie operatora.
NSArray *distinctArray = [arrayWithDuplicates
valueForKeyPath:@"@distinctUnionOfObjects.name"];
W twoim przypadku jednak, chcesz cały obiekt. To, co musisz zrobić, to podwójnie: 1) Zamiast tego użyj @distinctUnionOfArrays
. Na przykład. Jeśli te niestandardowe obiekty pochodzą z innych kolekcji, użyj @distinctUnionOfArray.myCollectionOfObjects
2) Wprowadź isEqual:
dla tych obiektów, aby powrócić, jeśli ich.Nazywa się to równa
Wdrożenie IsEqual aby Twoje obiekty porównywalne:
@interface SomeObject (Equality)
@end
@implementation SomeObject (Equality)
- (BOOL)isEqual:(SomeObject*)other
{
return self.hash == other.hash;
}
- (NSUInteger)hash
{
return self.name;///your case
}
@end
Jak używać:
- (NSArray*)distinctObjectsFromArray:(NSArray*)array
{
return [array valueForKeyPath:@"@distinctUnionOfObjects.self"];
}
Jest to dość proste w jednej linii
NSArray *duplicateList = ...
Jeśli nie interesuje cię wtedy porządek elementów (nieuporządkowany)
NSArray *withoutDUP1 = [[NSSet setWithArray:duplicateList] allObjects];
przechowywać elementy w kolejności, a następnie (zamówić)
NSArray *withoutDUP2 = [[NSOrderedSet orderedSetWithArray:duplicateList] array];
Ale jak filtrowanie twojego kodu bazuje na polu "nazwa"? – Satyam
są takie elementy w pojemniku Objective-C jak NSArray lub C/C++ (np std :: wektor lub tablica C)? –
dlaczego tag C? –
sorry usunięto tag, jego cel c tablicy z niestandardowymi obiektami ... "name" jest jedną z jego zmiennych członkowskich, chcę filtrować w oparciu o tę "nazwę" wartości. –