Удаление дубликатов из массива в объекте c
У меня есть массив с пользовательскими объектами. Каждый элемент массива имеет поле с именем "name". Теперь я хочу удалить повторяющиеся записи на основе этого значения имени.
Как мне добиться этого.
Спасибо заранее.
Ответы
Ответ 1
Возможно, вам придется написать этот метод фильтрации самостоятельно:
@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
Ответ 2
Я не знаю какого-либо стандартного способа сделать это, предоставленного фреймворками. Поэтому вам придется делать это в коде. Что-то вроде этого должно быть выполнимым:
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];
}
}
Ответ 3
Я знаю, что это старый вопрос, но вот еще одна возможность, в зависимости от того, что вам нужно.
Apple действительно предоставляет способ сделать это - Операторы коллекции кодирования ключевого значения.
Операторы объектов позволяют вам действовать в коллекции. В этом случае вы хотите:
@distinctUnionOfObjects
Оператор @distinctUnionOfObjects возвращает массив, содержащий отдельные объекты в свойстве, заданном по пути ключа справа от оператора.
NSArray *distinctArray = [arrayWithDuplicates
valueForKeyPath:@"@distinctUnionOfObjects.name"];
В вашем случае вам нужен весь объект. Так что вам нужно будет сделать два раза:
1) Вместо этого используйте @distinctUnionOfArrays
. Например. Если у вас есть эти пользовательские объекты из других коллекций, используйте @distinctUnionOfArray.myCollectionOfObjects
2) Внесите isEqual:
в те объекты, которые будут возвращены, если их .name равны
Ответ 4
Я собираюсь получить flak для этого...
Вы можете преобразовать ваш массив в словарь. Не уверен, насколько это эффективно, зависит от вызова реализации и сравнения, но он использует хэш-карту.
//Get unique entries
NSArray *myArray = @[@"Hello", @"World", @"Hello"];
NSDictionary *uniq = [NSDictionary dictionaryWithObjects:myArray forKeys:myArray];
NSLog(@"%@", uniq.allKeys);
* Обратите внимание: это может изменить порядок вашего массива.
Ответ 5
Если вы хотите, чтобы ваши пользовательские подклассы NSObject считались равными, когда их имена равны, вы можете реализовать isEqual:
и hash
. Это позволит вам добавить объекты к NSSet
/NSMutableSet
(набор различных объектов).
Затем вы можете легко создать отсортированный NSArray
с помощью метода NSSet
sortedArrayUsingDescriptors:
.
MikeAsh написал довольно солидную статью о реализации пользовательского равенства: Friday Q & A 2010-06-18: Реализация равенства и хищения
Ответ 6
Если вас беспокоит порядок
NSArray * newArray =
[[NSOrderedSet orderedSetWithArray:oldArray] array]; **// iOS 5.0 and later**
Ответ 7
Внесите 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"];
}
Ответ 8
Это довольно просто в одной строке
NSArray *duplicateList = ...
Если вам не нужен порядок элементов, то (неупорядоченный)
NSArray *withoutDUP1 = [[NSSet setWithArray:duplicateList] allObjects];
Сохраняйте элементы в порядке, затем (упорядоченном)
NSArray *withoutDUP2 = [[NSOrderedSet orderedSetWithArray:duplicateList] array];