У меня есть класс (colorClass), который содержит 2 NSStrings (idNumber и favoriteColor). Существует NSMutableArray (arrayColor), который содержит более 50 000 объектов colorClass. Каков самый быстрый способ найти все дубликаты idNumbers из всех объектов colorClass и вернуть их в массив? Прямо сейчас я использую цикл 1 для цикла, который копирует arrayColor, а затем фильтрует скопированный массив с использованием NSPredicate. Это занимает более 5 минут, чтобы отсортировать массив. Как это можно сделать более эффективно?Поиск дубликатов в NSMutableArray
ответ
Вы когда-нибудь думали об использовании NSMutableSet
? Наборы не позволяют дублировать в первую очередь, поэтому ваша проблема не будет существовать. Однако набор не будет работать, если порядок цветов будет иметь значение (поскольку наборы не имеют понятия упорядочения). Я не уверен в вашем конкретном случае.
«быстрый» потребует профилирования, но моя склонность будет сделать NSCountedSet из массива, огибать, что и возвращает массив элементов из считанного набора, имеет countForObject:
больше 1.
Первых вопрос: действительно ли порядок? Если нет, используйте NSMutableSet
или NSMutableDictionary
(в зависимости от того, что имеет смысл для вашего приложения)
Самый простой способ устранить дубликаты - это предотвратить их появление в первую очередь. Прежде чем добавить что-нибудь в свой NSMutableArray
, вы можете проверить, существует ли это значение. Например:
- (void)addColor:(NSString *)color withID:(NSString *)id {
NSArray *duplicates = [myArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"id == %@", id]];
if ([duplicates count] > 0) {
// Optionally report an error/throw an exception
return;
}
}
В противном случае, вы, вероятно, лучше от получения списка идентификаторов с помощью valueForKeyPath:
, то сортировка этого массива, а затем проходит через него один раз, чтобы искать дубликаты. Он бы soemthing так:
- (NSSet *)checkForDuplicateIDs {
NSArray *allIDs = [myArray valueForKeyPath:@"id"];
NSArray *sortedIDs = [allIDs sortedArrayUsingSelector:@selector(compare:)];
NSString *previousID = nil;
NSMutableSet *duplicateIDs = [NSMutableSet set];
for (NSString *anID in sortedIDs) {
if ([previousID isEqualToString:anID]) {
[duplicateIDs addObject:anID];
}
previousID = anID;
}
return [[duplicateIDs copy] autorelease];
}
Имейте в виду, однако, что сортировка списка по-прежнему, в лучшем случае, вероятно O(n log(n))
операцию. Если вы можете как минимум сохранить свои объекты в своем списке, вы можете избежать затрат на их сортировку. Предотвращение дубликатов лучше всего, поэтому сортировка списка лучше, а алгоритм, который я дал выше, является, вероятно, наихудшим.
Итак, чтобы немного рассказать о моих предыдущих комментариях: мне непонятно, из контекста, в котором эти данные используются. В частности, необходимо ли сохранить все эти объекты в большом длинном массиве. Если этого не происходит, словарь может быть лучшим выбором структуры данных вместо массива.
Поскольку словари являются неотъемлемо важными структурами данных, ColorClass
, вероятно, можно было бы полностью устранить, но я буду здесь предполагать, что есть еще одна причина, чтобы держать его вокруг, помимо того, что мы знаем из вопроса.
Если дубликаты не должны быть позволены произойти вообще, то словарь может хранить отдельные элементы, а код может выглядеть примерно так:
// colors is an NSMutableDictionary
- (ColorClass*)addColorIfPossible:(ColorClass*)color {
ColorClass *existingColor = [[colors objectForKey:[color idNumber]] retain];
if(existingColor == nil) {
[colors setObject:color forKey:[color idNumber]];
}
return [existingColor autorelease];
}
И если дубликаты разрешены, но существует необходимость для извлечения всех объектов с общим ID быстро, то словарь либо массивов или наборов может работать:
// colors is an NSMutableDictionary
- (void)addColor:(ColorClass*)color {
NSMutableSet *colorSet = [colors objectForKey:[color idNumber]];
if(!colorSet) {
// kInitialSetCapacity is a constant with some reasonable value you choose
colorSet = [NSMutableSet setWithCapacity:kInitialSetCapacity];
[colors setObject:colorSet forKey:[color idNumber]];
}
[colorSet addObject:color];
}
- (NSSet*)findDuplicatesForID:(NSString*)idNumber {
// returns nil if no colors with that id, but could
// return an empty set instead with little effort
return [[[colors objectForKey:idNumber] copy] autorelease];
}
Если есть необходимость в приложении к как имеют гигантский список цветов в общем порядке, и, чтобы быстро найти дубликаты, а затем классическое пространство противвременная компромисс: используйте только массив или поддерживайте как этот массив, так и словарь.
NSMutableSet *uniqueSet = [NSMutableSet setWithArray:arrayOfDuplicates];
arrayOfDuplicates = [uniqueSet allObjects];
Это может быть быстрее:
if ([theArray containsObject:theNumber]) {
// remove object
}
- 1. Поиск NSMutableArray
- 2. NSMutableArray, сохраняющий int без дубликатов
- 3. Поиск NSString в NSMutableArray
- 4. Поиск в NSMutableArray
- 5. Поиск в NSMutableArray
- 6. Поиск дубликатов в массиве
- 7. Поиск дубликатов в строке
- 8. Поиск дубликатов в C
- 9. Поиск дубликатов в массивах
- 10. Поиск дубликатов в массиве
- 11. Поиск дубликатов в колонке
- 12. удаление дубликатов из NSMutableArray с помощью NSSet
- 13. Слияние NSMutableArray с NSArray, фильтрация дубликатов
- 14. Excel - поиск дубликатов
- 15. Поиск дубликатов строк
- 16. Поиск дубликатов счетов
- 17. SQL Поиск многострочных дубликатов
- 18. Поиск дубликатов Java/SQL
- 19. Поиск дубликатов файлов изображений
- 20. MySQL - поиск дубликатов кортежей
- 21. Поиск дубликатов с SQL?
- 22. Поиск дубликатов документов
- 23. Поиск дубликатов записей в файле
- 24. Поиск всех дубликатов в массиве
- 25. Поиск вложенных дубликатов в OCL
- 26. Поиск дубликатов в массиве объектов
- 27. Поиск дубликатов элемента в массиве
- 28. Python: поиск дубликатов в списке
- 29. Поиск дубликатов записей в коллекции
- 30. Поиск/удаление дубликатов в BigData
Или возможно, 'NSMutableDictionary', так как мы говорим о пар ключ-значение .... –
Он хранения объекта с парой ключ-значение , а не сырой пары. Словарь не имеет смысла. –
Я не согласен. Большой массив объектов, каждый из которых является ключом + значением, в котором он заинтересован в поиске дубликатов, кажется идеальным для словаря. Если в некоторых случаях нет какой-то неотложной необходимости, чтобы все они были в последовательности. –