3

以下のような Student クラスがあるとします。

class Student {
    NSNumber *id;
    NSString *lastName;
    NSString *firstName; 
}

Web サービスからすべての学生のレコードを取得すると、すべての学生のレコードを格納する NSArray が作成されます。ある時点で、名前に基づいて特定の学生の記録を見つけるために配列を検索する必要があります。

studentsFirstNameDictionary という名前の辞書を作成するとします。

ですから、学生配列にオブジェクトを追加しながら、私はできる

Student objStudent = [[Student alloc] init];
objStudent.Id = someId;
objStudent.firstName = someName;
objStudent.lastName = someLastName;
[studentsDictionary setValue:iterationCounter forKey:objStudent.firstName];
[students addObject:objStudent];

以下のように検索を高速化するために、この辞書を作成することをお勧めします。また、どのような場合でも配列が必要であり、高速検索のために、上記のように姓と ID をキーとして、インデックスを値として格納する他の辞書を作成していると仮定してください。

-(Student*)getStudentByFirstName:(NSString *)firstName {
  int idxOfStudent = [ studentsDictionary valueForKey:firstName];
  return [students idxOfStudent];
}

このアプローチは、学生の配列を反復処理してファーストネームを比較し、一致する学生レコードを返すよりもパフォーマンスが優れていると思いますか?

テーブルビューにその配列を設定する必要があるため、常に学生配列が必要です。学生の記録を最初の名前、姓、またはIDですばやく検索できるように、配列にデータを入力しながら複数の辞書を作成するのが賢明かどうか疑問に思っています。

PS: 簡単にするために、すべての学生が一意の名、姓、および ID を持っていると考えてください。これにより、名、姓、または ID を値として格納する辞書を作成する際に問題が発生することはありません。

4

2 に答える 2

10

これは必要以上に複雑に聞こえます。通常、Cocoa では、この一般的なタスクについてデータ構造の教科書を調べていることに気付いた場合は、Foundation のドキュメントで何かを見逃しているか、時期尚早に最適化しているかのいずれかです。

オブジェクトの配列が与えられた場合Student、一意の属性を持つオブジェクトを取得するための迅速かつ簡単な方法が少なくともいくつかあります。

ブロック テストを使用します。

NSUInteger index = [studentArray indexOfObjectPassingTest:^(id obj, NSUInteger idx, BOOL *stop) {
    if ([obj.firstName isEqualToString:desiredFirstName]) {
        *stop = YES;  // keeps us from returning multiple students with same name
        return YES;
    } else
        return NO;
}];
if (index != NSNotFound)
    Student *desiredStudent = [studentArray objectAtIndex:index];

述語を使用します。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"firstName LIKE %@", desiredFirstName];
NSArray *filteredArray = [studentArray filteredArrayUsingPredicate:predicate];
Student *desiredStudent = [lastObject]; // only object if we assume firstNames are unique

これらはどちらも、Studentクラスがそれらのフィールド (つまり、インスタンス変数だけではない) のプロパティ (または KVC 準拠のアクセサー) を宣言していることを前提としています。

名前で学生に頻繁にアクセスしている場合は、名前をStudentオブジェクトにマッピングする辞書を検討することをお勧めします。

NSMutableDictionary *studentsByName = [NSMutableDictionary dictionaryWithCapacity:[students count]];
for (Student *student in students)
    [studentsByName setObject:student forKey:[student firstName]];

非常に多くの学生がいて、さまざまな属性で検索したい場合は、コア データについて学習することを検討してください。

于 2012-04-13T23:00:17.880 に答える
1

配列はまったく必要ないと思います。

Student オブジェクトを作成します。

Student objStudent = [[Student alloc] init];
objStudent.Id = someId;
objStudent.firstName = someName;
objStudent.lastName = someLastName;
[studentsDictionary setObject:student forKey:objStudent.firstName];

生徒を検索するにはfirstName:

Student * theStudent = [ studentsDictionary objectForKey:firstName ] ;

からすべての Student オブジェクトを取得するには、次studentsDictionaryを使用します。

NSArray * allStudents = [ studentsDictionary allValues ] ;

ただし、これは、属性によってのみ学生を見つけることを前提としていfirstNameます.. @ricksterのソリューションは、一般的にはより良いかもしれません

于 2012-04-13T23:31:03.857 に答える