2012/03/22更新

[XCODE] NSArrayでのソートのやり方が分かんない!C言語出身者でない自分でも分かる方法を3つ探してみた。

このエントリーをはてなブックマークに追加      

久しぶりのiPhone開発ネタです。
今日は、Objective-Cで用意されている配列のNSArrayの中身をソートする方法を 3種類紹介したいと思います。
これを学べばより楽しくiPhoneアプリ作成できるかも(*´∇`*)




【1】一般的な「sortedArrayUsingSelector:」から

NSArrayのソートで一番良く紹介されるのは、「sortedArrayUsingSelector:」だと思われます。
これはNSArrayに格納した中身のソート用メソッドを利用してソートを行う仕組みです。
一般的な例と一緒で、NSStringをソートしてみました。

画像
- (IBAction) sort1:(id)sender {
  // ソートするための配列を準備する。
  NSArray *array = [NSMutableArray arrayWithObjects:@"eee", @"ccc", @"bbb", @"aaa", @"ddd", nil];
  beforeLabel.text = [self concatArray:array with:@"\n"];
    
  // ソートする。
  // ソートする時に利用するのはcompare:というNSStringに用意された比較メソッド。
  array = [array sortedArrayUsingSelector:@selector(compare:)];
  afterLabel.text = [self concatArray:array with:@"\n"];




【2】自前関数を利用するsortedArrayUsingFunction:context:を用いたソート

自前の関数を用意して、ソートを行うことが出来ます。
自前の関数では、引数で受け取った2つの大きさを比較して、intを返します。
下記の例では、NSNumberを比較して、ソートしています。

画像

// ソートする為の比較関数。
// NSNumberからintを取り出して大きさ比較した結果を返す。
int sortArray(id item1, id item2, void *context) {    
  int number1 = [item1 intValue];
  int number2 = [item2 intValue];
  return number1 - number2;
}

- (IBAction) sort2:(id)sender {

  // ソートする対象の配列を作成する。
  NSNumber *n1 = [[NSNumber alloc] initWithInt:100];
  NSNumber *n2 = [[NSNumber alloc] initWithInt:90];
  NSNumber *n3 = [[NSNumber alloc] initWithInt:2000];
  NSNumber *n4 = [[NSNumber alloc] initWithInt:10];
  NSNumber *n5 = [[NSNumber alloc] initWithInt:40];
  NSArray *array = [NSMutableArray arrayWithObjects:n1, n2, n3, n4, n5, nil];
  beforeLabel.text = [self concatArray:array with:@"\n"];
    
  // 上で定義した自前の関数を用いてソートする。
  // 自前の関数なので、ソート結果を自由にコントロール出来る。
  array = [array sortedArrayUsingFunction:sortArray context:nil];
  afterLabel.text = [self concatArray:array with:@"\n"];
}




【3】ブロックを利用してソートするsortedArrayUsingComparator:

最後に紹介するのは、処理ブロック(クロージャー)で比較関数を記述する方式です。
ちょっとカッコいい感じかもしれません(・∀・)
以下の例では、CGSizeが配列に入っていて、比較関数ではCGSizeから作成した面積の大きさを比較します。

画像

- (IBAction) sort3:(id)sender {

  // ソート対象の配列を作成する。 
  NSValue *v1 = [NSValue valueWithCGSize:CGSizeMake(10, 20)];
  NSValue *v2 = [NSValue valueWithCGSize:CGSizeMake(100, 120)];
  NSValue *v3 = [NSValue valueWithCGSize:CGSizeMake(3, 2)];
  NSValue *v4 = [NSValue valueWithCGSize:CGSizeMake(120, 200)];
  NSValue *v5 = [NSValue valueWithCGSize:CGSizeMake(1220, 2011)];    
  NSArray *array = [NSMutableArray arrayWithObjects:v1, v2, v3, v4, v5, nil];
  beforeLabel.text = [self concatArray:array with:@"\n"];
    
  // ^{}で定義された処理ブロックを利用したソート方式。
  // 一回限りのソートとか比較関数の使い回しをしないなら、これ便利。
  array = [array sortedArrayUsingComparator:^(id item1, id item2){
      CGSize size1 = [item1 CGSizeValue];
      CGSize size2 = [item2 CGSizeValue];
      return (int)(size1.width*size1.height - size2.width*size2.height);
  }];
  afterLabel.text = [self concatArray:array with:@"\n"];
}




最後に

ソート処理が出来るようになると、UITableViewなどの一覧表示で出来る事も増えて楽しいかも。
基本的だけど残しておくと便利なこと、他にも色々とあると思うので、 見つける度にブログに今後も残しておこっと♪(´ε` )






こんな記事もいかがですか?

RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。