-3

I store NSObject (person) in NSMutableArray (self.tableData).

I would like to use section like in Address contact : sort alphabetically every fullName in my NSMutableArray (already done), and access it with index on the right "A,B,C,D..."

I have to get the first letter of person.fullName, but I don't succeed to loop it. Maybe I have to use substringWithRange or subStringToIndex ? I don't really understand the difference.

Here is my code :

- (void)viewDidLoad
{
    [super viewDidLoad];
self.tableData = [[NSMutableArray alloc] init];
    self.contactSectionTitles = [[NSArray alloc] init];
    self.contactIndexTitles = @[@"A", @"B", @"C", @"D", @"E", @"F", @"G", @"H", @"I", @"J", @"K", @"L", @"M", @"N", @"O", @"P", @"Q", @"R", @"S", @"T", @"U", @"V", @"W", @"X", @"Y", @"Z"];
    [self getPersonOutOfAddressBook];


    // Dictionary will hold our sub-arrays
    self.dicoAlphabet = [NSMutableDictionary dictionary];

    // Iterate over all the values in our sorted array
    for (Person *person in self.tableData) {

        // Get the first letter and its associated array from the dictionary.
        // If the dictionary does not exist create one and associate it with the letter.
        NSString *firstLetter = [person.fullName substringToIndex:1];
        NSMutableArray *arrayForLetter = [self.dicoAlphabet objectForKey:firstLetter];
        if (arrayForLetter == nil) {
            arrayForLetter = [NSMutableArray array];
            [self.dicoAlphabet setObject:arrayForLetter forKey:firstLetter];
        }

        // Add the value to the array for this letter
        [arrayForLetter addObject:person];
    }

    // arraysByLetter will contain the result you expect
    self.contactSectionTitles = [[self.dicoAlphabet allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

}

cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.accessoryType = UITableViewCellAccessoryNone;
        Person *person = [self.tableData objectAtIndex:indexPath.row];
//        cell.textLabel.text = person.fullName;

        NSString *sectionTitle = [self.contactSectionTitles objectAtIndex:indexPath.section];
        NSArray *sectionPerson = [self.dicoAlphabet objectForKey:sectionTitle];
        NSString *fullName = [sectionPerson objectAtIndex:indexPath.row];
        cell.textLabel.text = fullName;
        cell.detailTextLabel.text = person.mainNumber;
}
Vjardel
  • 1,065
  • 1
  • 13
  • 28
  • You say "don't succeed to loop it". OK, so what happened? FYI, `substringToIndex` is just a more convenient version of `substringWithRange` when you're grabbing the first characters. – Rob Aug 20 '15 at 15:33
  • 1
    So what is the problem? Your code looks good, does it work as expected? – Avt Aug 20 '15 at 15:39
  • Yep, looks good to me, too. The resulting `dicoAlphabet` is populated properly, as is `contactSectionTitles`. – Rob Aug 20 '15 at 15:40
  • 1
    FYI - Don't use your own hardcoded letter index. Use the `UILocalizedIndexedCollation` to help build the data. – rmaddy Aug 20 '15 at 15:41
  • @Rob The loop works well finally ! But nothing appears on my UITableView, maybe the cellForRowAtIndexPath has error... I'm searching (edited) – Vjardel Aug 20 '15 at 15:47
  • Could be a ton of things: Bad `cellForRowAtIndexPath`. Not returning right count from `numberOfRowsInSection`. Incorrect constraints in the cell. Etc. You need to add breakpoints or logging statements and confirm every step of the process. No offense intended, but I'd suggest spending a little more time debugging the code before posting any follow-up questions. I'd suggest you close/delete this question until that point. Or accept Mihai's answer to the first part of your question. – Rob Aug 20 '15 at 15:54

1 Answers1

2

substringWithRange gives you a string between 2 indexes like in the following example:

NSString *str = @"Hey Alex”;
str = [str substringWithRange:NSMakeRange(1,4)]; //"ey A"

while subStringToIndex will return a substring from the start or your string until the specified index like in the example:

NSString *str = @"Hey Alex";
str = [str substringToIndex:3]; //"Hey"

So if you need the first letter, you are better off with * subStringToIndex*

Mihai Fischer
  • 329
  • 2
  • 11