将自定义对象的NSArray转换为带有索引的按字母顺序排列的UITableView?

时间:2010-10-25 20:51:27

标签: iphone objective-c uitableview ios nsarray

(嗯......长标题)

如果我开始使用NSArray自定义对象(每个对象都是Person),就像这样:

{
  surname:Allen   forename: Woody,
  surname:Baxter  forename: Stanley,
  surname:Clay    forename: Cassius
}

...等。

您可以看到该数组已按姓氏顺序排列。如何使用该数组创建一个带有节标题A,B C等的UITableView,以及一个垂直运行的索引节点

                                                               A
                                                               B
                                                               C

修改

我想我要问的是如何将我的对象数组转换为一个截面数组,包含Surnames的所有首字母,以及一个Surname数组,它可能是这样的嵌套数组:

{ 
  letter: a
  {  surname:Allen   forename: Woody   }
  letter: b
  {  surname:Baxter  forename: Stanley }
  etc
} 

实际上,也许只是一个嵌套数组。

2 个答案:

答案 0 :(得分:3)

可能有一百万种方法可以做到这一点:)这是一个可行的方法(我相信它可以做得更漂亮,但因为没有人回答):

NSMutableDictionary *aIndexDictionary = [[NSMutableDictionary alloc] init]; 
NSMutableArray *currentArray;
NSRange aRange = NSMakeRange(0, 1);
NSString *firstLetter;
for (Person *aPerson in personArray) {
  firstLetter = [aPerson.surname substringWithRange:aRange];
  if ([aIndexDictionary objectForKey:firstLetter] == nil) {
    currentArray = [NSMutableArray array];
    [aIndexDictionary setObject:currentArray forKey:firstLetter];
  }
  [currentArray addObject:aPerson];
}

未经测试...

答案 1 :(得分:0)

约瑟夫·图拉的答案有很多问题,正如他所提到的那样未经测试。以下是问题:

1)如果名称为nil或@“”,[aPerson.name substringWithRange:aRange]将崩溃;

2)如果firstLetter已经在键列表中,则当前数组不会重置为指向属于键firstLetter的数组对象。因此,如果currentArray以前指向一个数组,其字典中的键是'K',但当前firstLetter是'P'已经作为键存在,那么将添加名称(以该字母'P'开头)到以'k'开头的名字数组。那里的大问题。

3)由于案例的不同,Jassie被添加到不同的数组到jassie(大写和小写'k'被区别对待)。

因此,作为对约瑟夫答案的重大改进,第2点至关重要,这是对未来用户更准确的实施:

-(NSDictionary*)indexArrayByName:(NSArray*)people
{
    NSMutableDictionary *anIndexedDict = [[NSMutableDictionary alloc] init];
    NSMutableArray *currentArray = nil;
    NSRange aRange = NSMakeRange(0, 1);
    NSString *firstLetter;

    for(Person *aPerson in people)
    {
        if(aPerson.name.length)
            firstLetter = [[aPerson.name substringWithRange:aRange] uppercaseString];
        else
            firstLetter = @"noName";//find own way to identify these

        if(![anIndexedDict.allKeys containsObject:firstLetter])
        {
            currentArray = [NSMutableArray array];
            anIndexedDict[firstLetter] = currentArray;
        }
        currentArray = anIndexedDict[firstLetter];
        [currentArray addObject:aPerson];
    }    
    return anIndexedDict;
}

可以添加其他改进,例如删除前导空格等,但我只是想提到主要问题。我测试了约瑟夫对这些问​​题的答案,然后我确保他们被淘汰:)。向约瑟夫提出主要想法。欢呼声。