Я бы создал новый класс с именем ItemGroup
, а затем добавил бы дополнительный ivar с именем 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
было установлено, прежде чем устанавливать время. При этом вам вообще не понадобится этот цикл сортировки. Дескрипторов sortDescriptors было бы достаточно.
person
e.James
schedule
03.02.2010