連載
» 2009年01月21日 00時00分 公開

Cocoaの素、Objective-Cを知ろう(5):配列とループ処理を理解しよう (3/4)

[竹下肯己,株式会社 qnote]

ディクショナリ(連想配列)

 一般的に配列には、機械的な連番(インデックス)で要素を管理する「通常配列」と、意味のあるキーワードを目印として要素を管理する「連想配列」の2種類があります。Objective-Cでは、NSArrayやNSMutableArrayで通常配列を実現する一方、「NSDictionary」と「NSMutableDictionary」で連想配列を実現することができます。また、これらのクラス名が表すとおり、Objective-Cでは連想配列のことを「ディクショナリ(辞書)」と表現します。

 NSDictionaryは内容が固定、NSMutableDictionaryは内容が可変のディクショナリを実現します。まずはNSDictionaryの利用例を見てみましょう。

#import <Foundation/Foundation.h>
int main(void) {
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  //(1)値, キー, 値, キー……で指定してディクショナリを生成
  NSDictionary *dict1 = [NSDictionary dictionaryWithObjectsAndKeys:
                         @"miro", @"name",
                         [NSNumber numberWithInt:8], @"age",
                         @"red" , @"color"
                         ,nil];
  //(2)値とキーを、それぞれ配列で指定してディクショナリを生成
  NSArray *keys = [NSArray arrayWithObjects:
                   @"name", @"age", @"color", nil];
  NSArray *vals = [NSArray arrayWithObjects:
                   @"futaba",
                   [NSNumber numberWithInt:4],
                   @"white", nil];
  NSDictionary *dict2 = [NSDictionary dictionaryWithObjects:vals forKeys:keys];
  //(3)キーを指定して要素を取得
  id obj1 = [dict1 objectForKey:@"name"];
  //(4)値とキーを、それぞれ配列として取得
  NSArray *kArr = [dict1 allKeys];
  NSArray *vArr = [dict1 allValues];
  //(5)ディクショナリの要素数を取得
  int dictCount = [dict1 count];
  //(6)ディクショナリの比較
  BOOL isDictEquals = [dict1 isEqualToDictionary:dict2];
  NSLog(@"%@", dict1);
  NSLog(@"%@", dict2);
  NSLog(@"%@", obj1);
  NSLog(@"%@", kArr);
  NSLog(@"%@", vArr);
  NSLog(@"%d", dictCount);
  NSLog(@"%d", isDictEquals);
  [pool drain];
  return 0;
}
main.m

 (1)と(2)は、キーや値を指定してNSDictionaryを生成する方法です。先ほどNSArrayのところでも説明したとおり、オブジェクトの並びの最後には必ずnilをセットします。また、これも最初に述べましたが、Objective-Cの配列やディクショナリにはオブジェクトしかセットできないので、上記の例のように数値はNSNumberのオブジェクトとしてセットします。

 なお、ディクショナリの生成用には、イニシャライザとして「initWithObjectsAndKeys:」や「initWithObjects:forKeys:」も用意されています(引数は、それぞれ「dictionaryWithObjectsAndKeys:」「dictionaryWithObjects:forKeys:」と同じです)。

 (3)は、キーを指定してディクショナリの要素にアクセスしています。指定されたキーが存在しない場合にはnilが返されます。

 (4)は、ディクショナリのキーだけの配列、要素だけの配列を、それぞれNSArrayとして取得するためのメソッドです。

 (5)は、ディクショナリに含まれる要素の数を返します。

 (6)の「isEqualToDictionary:」メソッドは、2つのディクショナリが等しいかどうかを返すメソッドです。キーと値の組み合わせがすべて一致しているかを評価します。また、オブジェクトの突き合わせには、NSArrayの場合と同じく、それぞれのクラスのisEqualメソッドが利用されます。

変更可能なディクショナリ

 ディクショナリの内容を変更可能にしたい場合には、「NSMutableDictionary」クラスを利用します。以下にNSMutableDictionaryの利用例を示します。

#import <Foundation/Foundation.h>
int main(void) {
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  //(1)空のディクショナリを生成
  NSMutableDictionary *mDict = [NSMutableDictionary dictionary];
  //(2)要素をセット
  [mDict setObject:@"miro" forKey:@"name"];
  [mDict setObject:[NSNumber numberWithInt:8] forKey:@"age"];
  [mDict setObject:@"red" forKey:@"color"];
  //(3)要素を削除
  [mDict removeObjectForKey:@"age"];
  [mDict removeObjectsForKeys:
    [NSArray arrayWithObjects:@"name", @"age", nil]];
  [mDict removeAllObjects];
  //(4)ディクショナリから要素を追加
  NSMutableDictionary *mDict2 =
    [NSMutableDictionary dictionaryWithObjectsAndKeys:
                       @"futaba", @"name",
                       [NSNumber numberWithInt:4], @"age",
                       @"white", @"color", nil];
  [mDict addEntriesFromDictionary:mDict2];
  NSLog(@"%@", mDict);
  [pool drain];
  return 0;
}
main.m

 (1)では、空っぽの状態でNSMutableDictionaryを生成しています。

 NSArrayに対するNSMutableArrayと同様に、NSMutableDictionaryはNSDictionaryのサブクラスとなっています。従って、上記以外のインスタンス生成方法や基本メソッド群は、NSDictionaryの機能をそのまま利用できます(1つ前のNSDictionaryのコード例を参照してください)。

 (2)の「setObject:」は、キーを指定してディクショナリに要素をセットするメソッドです。新規の要素追加も、既存キーの要素の置換もこのメソッドで実行します。

 (3)はディクショナリの要素を削除するメソッドの一部です。

 (4)は別のディクショナリから要素を追加します。2つのディクショナリに同じキーが存在した場合、新たに追加する方のディクショナリの要素で上書きされます。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。