NSMutableArray
のソートについて質問があります。使うことができます sortedArrayUsingDescriptors:
オブジェクトを使用して配列をソートするメソッド。
たとえば、NSMutableArray
のplaces
があり、属性frequency
(int値)があり、frequency
で降順でソートしたいのですが、それを正しく使用する方法を知っている。
initWithKey
にキーとして何を入れますか?
私のオブジェクトplace
には以下が含まれます:
NSString * name;
NSString * address;
NSString * frequency;
NSString * type;
NSMutableArray * places;
... populate array with objects ...
NSSortDescriptor * sortByFrequency =
[[[NSSortDescriptor alloc] initWithKey:@"????????" ascending:NO] autorelease];
NSArray * descriptors = [NSArray arrayWithObject:sortByFrequency];
NSArray * sorted = [x sortedArrayUsingDescriptors:descriptors];
オブジェクトの配列を並べ替えるには:
NSSortDescriptor
-変数の名前をキーとして使用して、ソートのための記述子と、それらのキーで実行されるセレクターをセットアップしますNSSortDescriptor
を使用して記述子の配列を取得します以下に2つの例を示します。1つはNSDictionary
とNSString/NSNumber
値はNSNumber
でソートし、もう1つは2つのNSString
フィールドでソートしたカスタムクラスを使用します。
Cocoaプログラミングトピックの NSArrayオブジェクトの並べ替えとフィルタリング に従って、その他の例と説明を参照してください。
例:
これはGNUStepで行われ、Cocoaでも同じように動作するはずです-コードはまったく同じです-私はMacの前に座ってみます:
NSString
値とNSNumber
値を使用した最初の例:NSNumber
値での並べ替え:
NSString * NAME = @"name";
NSString * ADDRESS = @"address";
NSString * FREQUENCY = @"frequency";
NSString * TYPE = @"type";
NSMutableArray * array = [NSMutableArray array];
NSDictionary * dict;
dict = [NSDictionary dictionaryWithObjectsAndKeys:
@"Alehandro", NAME, @"Sydney", ADDRESS,
[NSNumber numberWithInt:100], FREQUENCY,
@"T", TYPE, nil];
[array addObject:dict];
dict = [NSDictionary dictionaryWithObjectsAndKeys:
@"Xentro", NAME, @"Melbourne", ADDRESS,
[NSNumber numberWithInt:50], FREQUENCY,
@"X", TYPE, nil];
[array addObject:dict];
dict = [NSDictionary dictionaryWithObjectsAndKeys:
@"John", NAME, @"Perth", ADDRESS,
[NSNumber numberWithInt:75],
FREQUENCY, @"A", TYPE, nil];
[array addObject:dict];
dict = [NSDictionary dictionaryWithObjectsAndKeys:
@"Fjord", NAME, @"Brisbane", ADDRESS,
[NSNumber numberWithInt:20], FREQUENCY,
@"B", TYPE, nil];
[array addObject:dict];
NSNumber
であるFrequencyフィールドを持つ記述子を使用したパーツのソート:
NSSortDescriptor * frequencyDescriptor =
[[[NSSortDescriptor alloc] initWithKey:FREQUENCY
ascending:YES] autorelease];
id obj;
NSEnumerator * enumerator = [array objectEnumerator];
while ((obj = [enumerator nextObject])) NSLog(@"%@", obj);
NSArray * descriptors =
[NSArray arrayWithObjects:frequencyDescriptor, nil];
NSArray * sortedArray =
[array sortedArrayUsingDescriptors:descriptors];
NSLog(@"\nSorted ...");
enumerator = [sortedArray objectEnumerator];
while ((obj = [enumerator nextObject])) NSLog(@"%@", obj);
出力-頻度フィールドでソート:
2009-12-04 x[1] {address = Sydney; frequency = 100; name = Alehandro; type = T; }
2009-12-04 x[1] {address = Melbourne; frequency = 50; name = Xentro; type = X; }
2009-12-04 x[1] {address = Perth; frequency = 75; name = John; type = A; }
2009-12-04 x[1] {address = Brisbane; frequency = 20; name = Fjord; type = B; }
2009-12-04 x[1]
Sorted ...
2009-12-04 x[1] {address = Brisbane; frequency = 20; name = Fjord; type = B; }
2009-12-04 x[1] {address = Melbourne; frequency = 50; name = Xentro; type = X; }
2009-12-04 x[1] {address = Perth; frequency = 75; name = John; type = A; }
2009-12-04 x[1] {address = Sydney; frequency = 100; name = Alehandro; type = T; }
カスタムクラスと2つのNSString
変数でソートする2番目の例。
ソートする配列(下部のクラスA
を参照):
NSMutableArray * array = [NSMutableArray array];
[array addObject:[[A alloc] initWithFirstName:@"Alehandro"
lastName:@"Xentro"
age:[NSNumber numberWithInt:40]]];
[array addObject:[[A alloc] initWithFirstName:@"John"
lastName:@"Smith"
age:[NSNumber numberWithInt:30]]];
[array addObject:[[A alloc] initWithFirstName:@"John"
lastName:@"Smyth"
age:[NSNumber numberWithInt:25]]];
[array addObject:[[A alloc] initWithFirstName:@"Torro"
lastName:@"Ola"
age:[NSNumber numberWithInt:45]]];
[array addObject:[[A alloc] initWithFirstName:@"Alehandro"
lastName:@"Bento"
age:[NSNumber numberWithInt:41]]];
[array addObject:[[A alloc] initWithFirstName:@"Alehandro"
lastName:@"Axel"
age:[NSNumber numberWithInt:41]]];
ソート部分は、lastName、firstNameの順にソートします。
NSString * LASTNAME = @"lastName";
NSString * FIRSTNAME = @"firstName";
NSSortDescriptor *lastDescriptor =
[[[NSSortDescriptor alloc]
initWithKey:LASTNAME
ascending:YES
selector:@selector(localizedCaseInsensitiveCompare:)] autorelease];
NSSortDescriptor *firstDescriptor =
[[[NSSortDescriptor alloc]
initWithKey:FIRSTNAME
ascending:YES
selector:@selector(localizedCaseInsensitiveCompare:)] autorelease];
NSArray * descriptors =
[NSArray arrayWithObjects:lastDescriptor, firstDescriptor, nil];
NSArray * sortedArray =
[array sortedArrayUsingDescriptors:descriptors];
結果を印刷します。
NSLog(@"\nSorted ...");
enumerator = [sortedArray objectEnumerator];
while ((obj = [enumerator nextObject])) NSLog(@"%@", obj);
結果(ソートの前後):
2009-12-04 00:52:16.637 x[11375] Alehandro, Xentro, age:40
2009-12-04 00:52:16.644 x[11375] John, Smith, age:30
2009-12-04 00:52:16.644 x[11375] John, Smyth, age:25
2009-12-04 00:52:16.644 x[11375] Torro, Ola, age:45
2009-12-04 00:52:16.645 x[11375] Alehandro, Bento, age:41
2009-12-04 00:52:16.645 x[11375] Alehandro, Axel, age:41
2009-12-04 00:52:16.645 x[11375]
Sorted ...
2009-12-04 00:52:16.645 x[11375] Alehandro, Axel, age:41
2009-12-04 00:52:16.645 x[11375] Alehandro, Bento, age:41
2009-12-04 00:52:16.645 x[11375] Torro, Ola, age:45
2009-12-04 00:52:16.645 x[11375] John, Smith, age:30
2009-12-04 00:52:16.645 x[11375] John, Smyth, age:25
2009-12-04 00:52:16.645 x[11375] Alehandro, Xentro, age:40
クラスA
はNSObject
を拡張します-ここでは特別なものはありません:
#import <Foundation/Foundation.h>
@interface A : NSObject
{
NSString * firstName;
NSString * lastName;
NSNumber * age;
}
- (id)initWithFirstName:(NSString*)aFirstName
lastName:(NSString*)aLastName
age:(NSNumber*)anAge;
-(NSString* )description;
+(NSString*)action;
@end
実装:
#import <Foundation/Foundation.h>
#import "A.h"
@implementation A
- (id)init
{
return [self initWithFirstName:@"N/A"
lastName:@"N/A"
age:0];
}
- (id)initWithFirstName:(NSString*)aFirstName
lastName:(NSString*)aLastName
age:(NSNumber*)anAge
{
self = [super init];
if (!self) return nil;
firstName = [aFirstName copy];
lastName = [aLastName copy];
age = [anAge copy];
return self;
}
- (void)dealloc
{
[firstName release];
[lastName release];
[age release];
[super release];
}
- (NSString *) description
{
return [NSString stringWithFormat: @"%@, %@, age:%@",
firstName, lastName, age];
}
@end
「キー」は、オブジェクトのメソッド(配列「x」の要素)であり、ソートするものを返します。そのため、この場合、「頻度」でソートしたいと言いました。あとは、周波数を返すメソッドの名前をキーとして使用するだけです。
NSMutableArrayを並べ替える方法は次のとおりです。
NSMutableArray *numberSort =[[NSMutableArray alloc] init];
while ((key = [enumerator nextObject])) {
//(NSNumber *)integer = [key integerValue];
[numberSort addObject:[NSNumber numberWithInt:[key intValue]]];
// code that uses the returned key
}
NSArray *stringSort = [numberSort sortedArrayUsingSelector:@selector(compare:)];
enumerator = [stringSort objectEnumerator];
NSNumber *intKey;
NSMutableArray *backToString =[[NSMutableArray alloc] init];
while ((intKey = [enumerator nextObject])) {
//(NSNumber *)integer = [key integerValue];
[backToString addObject:[intKey stringValue]];
// code that uses the returned key