という名前の新しいクラスを作成し、アイテム クラスに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 で十分です。