Take the 2-minute tour ×

Okay I am trying to create an indexPath value from a NSArray of NSDictionary values so that when I go through to my tableview I can place an accessory tick on the side.

I have an NSArray of NSDictionaries that look like this

        HAS = 1;
        ISL = 1;
        ISV = 0;
        MAN = BANKING;
        MON = 324;

So the array would about 80 of these entries each with different values..

To create the IndexPath I would need to count the number of unique first letters of MAN until MAN == selected String This would give me the Section number.

Then I would need to count how many entries are in the selected section type for rows.

I have had some help already from here but I failed to identify a flaw in my logic.. for the row I was counting all of the entires instead of from the start of the selected section which ment my row count was totally stuffed. Below is a example of what I am trying to achieve.

a, aa, b, c, d, dd, ddd, dddd, e, f, g, gg

the user selects ddd so the indexpath would be


a, b, c, (d), e, f, g = 3


d, dd, (ddd), dddd = 2

I can get the section fine like so

NSArray *MANArray = [sortedArray valueForKey:@"MAN"];

NSMutableArray *letters = [NSMutableArray array];
NSString *currentLetter = nil;
for (NSString *string in MANArray) {
    if (string.length > 0) {
        NSString *letter = [string substringToIndex:1];
        if (![letter isEqualToString:currentLetter]) {
            [letters addObject:letter];
            currentLetter = letter;
NSArray *firstLetterArray = [NSArray arrayWithArray:letters];
int sectionCount = 0;
for(int i=0; i<[firstLetterArray count]; i++){
    if( [[firstLetterArray objectAtIndex:i] isEqualToString:completedStringLetter]){
        sectionCount = i;
        NSLog(@"%d", sectionCount);

But I am just stuck when trying to get the row count from the selected section.

any help would be HUGELY appreciated.


This is what I have done to count until the selected value but like I said its incorrect as it needs to start from the section depending on the first letter.

NSNumber * myNumber = [NSNumber numberWithInteger:[modIdString integerValue]];

NSArray *subarray = [sortedArray valueForKey:@"MOD"];
for(int i=0; i<[subarray count]; i++){
   if( [[subarray objectAtIndex:i] isEqualToNumber:myNumber]){
      //you have found it, do whatever you need, and break from the loop
      modelResultIndexPath = nil;
      modelResultIndexPath = [NSIndexPath indexPathForRow:sectionCount inSection:i];
share|improve this question

2 Answers 2

up vote 2 down vote accepted

How about converting the array with values "a, aa, b, c, d, dd, ddd, dddd, e, f, g, gg" to an NSDictionary of arrays as,

dict = {
        a = [a, aa];
        b = [b];
        c = [c];
        d = [d, dd, ddd, dddd];
        e = [e];
        f = [f];
        g = [g, gg];

and then [[dict allKeys] count] should give you the section count and [[dict valueForKey:@"d"] count] should give the corresponding row count.

In order to convert the array to array of dictionaries, Use this code,

NSArray *sortedArray = [arrayData sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
NSMutableDictionary *arraysByLetterDict = [NSMutableDictionary dictionary];

for (NSString *value in sortedArray) {
    NSString *firstLetter = [value substringWithRange:NSMakeRange(0, 1)];
    NSMutableArray *arrayForLetter = [arraysByLetterDict objectForKey:firstLetter];
    if (!arrayForLetter) {
        arrayForLetter = [NSMutableArray array];
        [arraysByLetterDict setObject:arrayForLetter forKey:firstLetter];
    [arrayForLetter addObject:value];
NSLog(@"Dictionary: %@", arraysByLetterDict);

Indexpath can be calculated as,

NSArray *allKeys = [[dict allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
int totalSectionCount = [allKeys count];
int totalRowCount = [[dict valueForKey:@"d"] count];

int sectionCount = [allKeys indexOfObject:@"d"];
int rowCount = [[dict valueForKey:@"d"] indexOfObject:@"ddd"];

modelResultIndexPath = [NSIndexPath indexPathForRow:rowCount inSection:sectionCount];
share|improve this answer
Since dictionary keys are unsorted you will run into an issue with getting sectionCount. To use this approach you will also need to maintain an ordered list of the keys (like the original code) or use a custom dictionary class that maintains the order. –  Edwin Iskandar Nov 7 '12 at 12:14
going to try this out now.. I have already sorted the array of dictionaries so this should hopefully work. –  HurkNburkS Nov 7 '12 at 19:33
@HurkNburkS, I have checked with the array string in your question and it looked to me like working. Check it and let me know. –  iDev Nov 7 '12 at 19:38
@HurkNburkS, section count and row count for "ddd" should be calculated as, int sectionCount = [[dict allKeys] indexOfObject:@"d"]; int rowCount = [[dict valueForKey:@"d"] indexOfObject:@"ddd"]; Corrected my answer. totalSectionCount and totalRowCount can be used to draw the table with sections and rows inside that. –  iDev Nov 7 '12 at 19:44
This is super close to working.. but its just giving me a slightly incorect row count.. I think maybe its starting from 1 or something.. instead of 0.. just trying to track it down atm. –  HurkNburkS Nov 7 '12 at 20:56

You can use a predicate on the original array of dictionaries to filter out all the dictionaries that begin with a particular letter, and then find the index of the matching one you are looking for using idexOfObjectPassingTest:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.MAN beginswith[c] '%@'", SELECTED_FIRST_LETTER_OF_MAN];
NSArray *filteredDictionaries = [sortedArray filteredArrayUsingPredicate:predicate];
int rowCount = [filteredDictionaries indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
    NSDictionary *dictionary = (NSDictionary *)obj;

    if ([dictionary[@"MAN"] isEqualToString:SELECTED_MAN]
        && [dictionary[@"MON"] isEqualToString:SELECTED_MON]) {
        return YES;
    } else {
        return NO;
share|improve this answer
ahh.. okay going to have a play will come back and mark your answer once i get it going. –  HurkNburkS Nov 7 '12 at 2:57
okay.. my fault I forgot MAN can have multiple instances that are identical.. the way to tell them apart is by using MON as its unique identifier... Painful I know. I have updated my question with the function I have created to count up till the selected value –  HurkNburkS Nov 7 '12 at 3:17
you can concatenate MAN+MON and create an array of those string. Then filter that using the same predicate above. –  Edwin Iskandar Nov 7 '12 at 3:30
What about somehow creating an array of dictionaries instead of just an array for filteredWords? would you have any idea on how to do that? –  HurkNburkS Nov 7 '12 at 3:34
updated answer to use the original dictionary –  Edwin Iskandar Nov 7 '12 at 3:59

Your Answer


