2014年2月3日月曜日

sortedArrayUsingDescriptorsを使ってソート

以前に、sortUsingComparatorを使って配列内にあるオブジェクトのソートをしました。


今回は sortedArrayUsingDescriptorsを使ってソートしてみます。
NSArrayのソートとしては、こちらの方が楽かもしれません。


ソートするオブジェクトと配列を用意する

前回と同様、以下のCatクラスを使用します。
@interface Cat : NSObject

@property (nonatomic,strong)NSString *name;
@property (nonatomic,assign)int age;

@end

@implementation Cat

- (NSString*)description
{
    return [NSString stringWithFormat:@"< Cat: age=%d , name=%@ >"
                ,self.age,self.name];
}

@end

配列も前回と同様に作ります。決して手抜きではありません。
NSMutableArray *array = [NSMutableArray arrayWithCapacity:4];
Cat *cat = [[Cat alloc] init];
cat.name = @"Toro";
cat.age = 5;
[array addObject:cat];
        
cat = [[Cat alloc] init];
cat.name = @"Tama";
cat.age = 5;
[array addObject:cat];
        
cat = [[Cat alloc] init];
cat.name = @"Doraemon";
cat.age = 3;
[array addObject:cat];
        
cat = [[Cat alloc] init];
cat.name = @"Dorami";
cat.age = 1;
[array addObject:cat];
        
NSLog(@"array = %@",array);
ログ出力の結果。
配列に格納した順番に、Catが表示されているのが分かります。
2013-09-03 11:59:41.774 SortTest[440:c07] array = (
    "< Cat: age=5 , name=Toro >",
    "< Cat: age=5 , name=Tama >",
    "< Cat: age=3 , name=Doraemon >",
    "< Cat: age=1 , name=Dorami >"
)

更に前回同様、この配列を年齢(age)を昇順にソートして、年齢が同じなら名前(name)を昇順にソートするようにしてみます。
違うのはsortedArrayUsingDescriptors:メソッドを使用する点です。

NSSortDescriptorオブジェクトの作成

まずは、NSSortDescriptorオブジェクトを作ります。
先に年齢でソートするので、Keyに@"age"という風に、Catクラスのプロパティ名を指定します。そして昇順に並べるので、ascendingにYESと指定します。
NSSortDescriptor *sort1 = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES];

次に名前でソートするので、名前ソート用のNSSortDescriptorオブジェクトを作ります。
Keyに@"name"という風に、Catクラスのプロパティ名を指定します。
NSSortDescriptor *sort2 = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];

sortedArrayUsingDescriptors:メソッドでソート

準備が整いました。あとはこのNSSortDescriptorオブジェクトをsortedArrayUsingDescriptors:メソッドに配列として渡してやるだけです。配列に格納する順番がソートするルールの順番になるので注意して下さい。

また、sortUsingComparator:メソッドの場合と違い、sortedArrayUsingDescriptors:はソートされた新しい配列を返すメソッドなので、その点もご留意を。
NSArray *array2 = [array sortedArrayUsingDescriptors:@[sort1,sort2]];
NSLog(@"sorted array = %@",array2);
ソート後のログ出力の結果です。
2014-02-02 15:59:55.679 NumberTest[40479:c07] sorted array = (
    "< Cat: age=1 , name=Dorami >",
    "< Cat: age=3 , name=Doraemon >",
    "< Cat: age=5 , name=Tama >",
    "< Cat: age=5 , name=Toro >"
)

名前は降順にソートしたい

年齢は昇順のままで、名前だけ降順にしたい。そんな場合にも簡単に対応できます。
先ほどのsort2オブジェクトの生成のところで、ascendingにNOを指定すれば降順に切り替わります。
NSSortDescriptor *sort2 = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:NO];

結果は以下の通り。
TamaとToroが入れ替わっているのが分かります。
2014-02-02 17:09:40.994 NumberTest[40515:c07] sorted array = (
    "< Cat: age=1 , name=Dorami >",
    "< Cat: age=3 , name=Doraemon >",
    "< Cat: age=5 , name=Toro >",
    "< Cat: age=5 , name=Tama >"
)

配列の中身がNSNumberやNSStringなら?

こちらの場合は、ただ単にKeyに@"self"と指定すればOKです。
NSSortDescriptor *sort3 = [NSSortDescriptor sortDescriptorWithKey:@"self" ascending:YES];
NSArray array3 = [anyArray sortedArrayUsingDescriptors:@[sort3]];

関連記事

0 件のコメント:

コメントを投稿

Related Posts Plugin for WordPress, Blogger...