@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)を昇順にソートするようにしてみます。
NSMutableArrayのsortUsingComparator:メソッドを使用してやってみます。
[array sortUsingComparator:^NSComparisonResult(Cat *cat1, Cat *cat2) { if (cat1.age<cat2.age) { return NSOrderedAscending; } if (cat1.age>cat2.age) { return NSOrderedDescending; } return [cat1.name compare:cat2.name]; }];ブロックの中で2つの要素を比較するロジックを記述し、NSComparisonResultを返します。
まず、cat1とcat2のageを比較して、cat1.ageの方が小さければ、NSOrderedAscendingを返します。Ascendingは昇順を意味します。
if (cat1.age<cat2.age) { return NSOrderedAscending; // 昇順を返す }対して、cat2.ageの方が小さければ、降順を表すNSOrderedDescendingを返してやります。
if (cat1.age>cat2.age) { return NSOrderedDescending; // 降順を返す }これらどちらでも無いという事は、2つのageは同じであるという事なので、今度は名前を比較します。
name(NSString)の比較にはcompare:メソッドが用意されているので、こちらを使うことにします。 compare:メソッドはNSComparisonResultを返すので、結果をそのままブロックの返り値に利用できます。
上記ソートを実行したあとにarrayをログ出力すると、以下のようになりました。
ソート前のログと較べてみて下さい。
2013-09-03 11:59:41.775 SortTest[440:c07] array = ( "< Cat: age=1 , name=Dorami >", "< Cat: age=3 , name=Doraemon >", "< Cat: age=5 , name=Tama >", "< Cat: age=5 , name=Toro >" )
よくある問題ですが、年齢を昇順ではなく、降順にするにはどうするのでしょうか?
ageを比較した結果のNSOrderedAscendingとNSOrderedDescendingを入れ替えてやります。
[array sortUsingComparator:^NSComparisonResult(Cat *cat1, Cat *cat2) { if (cat1.age<cat2.age) { return NSOrderedDescending; // 降順 } if (cat1.age>cat2.age) { return NSOrderedAscending; // 昇順 } return [cat1.name compare:cat2.name]; }];ソート後のログ出力は、以下のようになりました。
当然ですが、名前のソートは昇順のままです。降順にしたい場合は、各自チャレンジして下さい。
2013-09-03 12:24:24.789 SortTest[510:c07] array = ( "< Cat: age=5 , name=Tama >", "< Cat: age=5 , name=Toro >", "< Cat: age=3 , name=Doraemon >", "< Cat: age=1 , name=Dorami >" )
0 件のコメント:
コメントを投稿