Я бы создал новый класс с именем ItemGroup
, а затем добавил бы дополнительный ивар с именем group
к вашему классу предметов:
@interface ItemGroup : NSObject
{
NSNumber * time;
}
@property (nonatomic, copy) time;
@end
@interface ItemClass : NSobject
{
NSString * name;
NSNumber * time;
ItemGroup * group;
}
@property (nonatomic, copy) NSString * name;
@property (nonatomic, copy) NSNumber * time;
@property (nonatomic, assign) ItemClass * group; // note: must be assign
@end
Затем вы можете сделать следующее:
NSMutableDictionary * groups = [NSMutableDictionary dictionaryWithCapacity:0];
for (ItemClass * item in sourceData)
{
ItemGroup * group = [groups objectForKey:item.name];
if (group == nil)
{
group = [[ItemGroup alloc] init];
[groups setObject:group forKey:item.name];
[group release];
group.time = item.time;
}
else if (item.time < group.time)
{
group.time = item.time;
}
item.group = group;
}
Этот код перебирает несортированный массив, отслеживая минимальное время для каждой группы, а также устанавливает группу для каждого элемента. После этого вы просто сортируете по group.time
и time
:
NSSortDescriptor * groupSorter;
groupSort = [NSSortDescriptor sortDescriptorWithKey:@"group.time" ascending:YES];
NSSortDescriptor * timeSorter;
timeSort = [NSSortDescriptor sortDescriptorWithKey:@"time" ascending:YES];
NSArray * sortDescriptors = [NSArray arrayWithObjects:groupSort, timeSort, nil];
NSArray * sorted = [sourceData sortedArrayUsingDescriptors:sortDescriptors];
И это должно сработать!
ОБНОВЛЕНИЕ : обратите внимание, что вы могли бы получить намного лучшую производительность, если бы вы могли назначать группы прямо из ворот. Примерно так:
@interface ItemGroup : NSObject
{
NSString * name;
NSNumber * time;
}
@property (nonatomic, copy) NSString * name;
@property (nonatomic, copy) NSSNumber * time;
@end
@interface ItemClass : NSObject
{
ItemGroup * group;
NSNumber * time;
}
@property (nonatomic, retain) ItemGroup * group;
@property (nonatomic, copy) NSNumber * time;
@end
Теперь, если вы ведете список групп где-то (они могут даже где-то помещаться в массив, если это необходимо):
ItemGroup * group_A = [[ItemGroup alloc] init];
group_A.name = @"A";
ItemGroup * group_B = [[ItemGroup alloc] init];
group_B.name = @"B";
...
И вместо установки имен элементов данных вы устанавливаете их группу:
someItem.group = group_A;
someItem.time = GetSomeRandomTimeValue();
[sourceData addObject:someItem];
....
Это значительно упростит цикл, используемый для установки времени группы:
for (ItemClass * item in sourceData)
{
if (item.time < group.time) { group.time = item.time; }
}
И, если вы действительно хотите быть сверкающим быстро, вы можете даже изменить установщик свойства для своего свойства time
, чтобы установить время группы на лету:
@implementation ItemClass
- (void)setTime:(NSNumber *)newTime
{
if (newTime < group.time) { group.time = newTime; }
time = [newTime copy];
}
@end
Обратите внимание, что вы должны быть уверены, что group
было установлено, прежде чем установить время. С этим на месте, вам вообще не понадобится этот цикл сортировки. Сортировка дескрипторов будет достаточно.