3

假设我有一个学生课程,如下所示:

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]];

如果你有大量的学生并且想通过各种属性搜索他们,你可以考虑学习 Core Data。

于 2012-04-13T23:00:17.880 回答
1

我认为您根本不需要数组。

创建您的学生对象:

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 回答