vorrei creare una nuova classe chiamata ItemGroup
, e quindi aggiungere un Ivar aggiuntivo chiamato group
alla classe articolo:
@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
Poi, si potrebbe procedere come segue:
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;
}
Questo codice esegue il ciclo attraverso la matrice non ordinata, tenendo traccia del tempo minimo per ciascun gruppo e anche impostando il gruppo per ogni articolo. Con questo completo, è sufficiente ordinamento group.time
e 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];
E che dovrebbe fare il trucco!
UPDATE: Si noti che si potrebbe ottenere molto prestazioni migliori se tu fossi in grado di assegnare i gruppi dritto fuori dal cancello. Qualcosa di simile a questo:
@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
Ora, se si mantiene un elenco di gruppi da qualche parte (si potrebbe anche andare in un array da qualche parte, se necessario):
ItemGroup * group_A = [[ItemGroup alloc] init];
group_A.name = @"A";
ItemGroup * group_B = [[ItemGroup alloc] init];
group_B.name = @"B";
...
E invece di impostare i nomi dei vostri elementi di dati, è possibile impostare il loro gruppo:
someItem.group = group_A;
someItem.time = GetSomeRandomTimeValue();
[sourceData addObject:someItem];
....
Questo semplificherebbe notevolmente il ciclo utilizzato per impostare gli orari di gruppo:
for (ItemClass * item in sourceData)
{
if (item.time < group.time) { group.time = item.time; }
}
E, se si voleva davvero essere ardente veloce su di esso, si potrebbe anche modificare il setter di proprietà per la vostra proprietà time
per impostare i tempi di gruppo al volo:
@implementation ItemClass
- (void)setTime:(NSNumber *)newTime
{
if (newTime < group.time) { group.time = newTime; }
time = [newTime copy];
}
@end
Si noti che dovresti assicurarti che group
sia stato impostato prima di impostare l'ora. Con questo in atto, non avresti bisogno di quel ciclo di smistamento. Gli ordinatoriDescriptors sarebbero sufficienti.
Questo non risponde alla domanda: la mia situazione è più complicata del semplice ordinamento per nome. – Jaanus
@ Jaanus. Ohhh, vedo. Non ho notato che l'ordine dei gruppi dipende dal tempo. –
@ Jaanus. Ho aggiornato il codice in modo che risponda effettivamente alla domanda! –