I have an NSArray of NSDictionaries in my app. In each dictionary I hold an NSDate called "RunDate." The problem I am having now is that the code I am trying to do it with is very inefficient. Basically I only want one section per date out of all the dictionaries. Then in each section (sorted by that date), I would load the appropriate dictionary that had that date.
In the code below I made a new NSArray of NSDictionarys which held a date and number of that date (so I could know how many rows are in each section). The problem is, this code looks and feels very inefficient and I was wondering if there were any ways my code is incorrect or could be improved upon. There can be over 500 entries and the code I have now would be very slow. Does anyone have any suggestions on it?
runArray = [[NSMutableArray alloc] init];
runArray = [[[NSUserDefaults standardUserDefaults] arrayForKey:@"RunArray"] mutableCopy];
runDictTableArray = [[NSMutableArray alloc] init];
for (NSDictionary *dict in runArray) {
NSDictionary *runInfoDict = [[NSMutableDictionary alloc] init];
NSDate *theDate = [dict objectForKey:@"RunDate"];
//Check if we already have this date in the saved run array
BOOL goToNextDict = FALSE;
for (NSDictionary *savedDict in runDictTableArray) {
if ([theDate compare:[savedDict objectForKey:@"RunDate"]] == NSOrderedSame) {
goToNextDict = TRUE;
break;
}
}
if (goToNextDict)
continue;
////////////////////////////
//Now we check how many more we have of this date
int numbOfDate = 1;
int index = (int)[runArray indexOfObject:dict];
for (int i = index; i < [runArray count]; i++) {
NSDictionary *dictInner = [runArray objectAtIndex:i];
if ([theDate compare:[dictInner objectForKey:@"RunDate"]] == NSOrderedSame) {
numbOfDate++;
}
}
////////////////////////////
[runInfoDict setValue:[NSNumber numberWithInt:numbOfDate] forKey:@"DateAmount"];
[runInfoDict setValue:theDate forKey:@"Date"];
[runDictTableArray addObject:runInfoDict];
}
Some suggestions:
NSMutableDictionary
, rather than a NSMutableArray
of NSDictionary
. While looping through runArray
, check if your dictionary has a value for your date (objectForKey
returns a value). If it does, add 1 to the count. If it does not, add that date as a key to the dictionary with a value of 1. This way, you won't have to do the inner loop to get the number of times a date occurs. You won't need the 'go to next dictionary' logic either, I would think.runArray = [[NSMutableArray alloc] init];
doesn't really do anything since you're immediately re-assigning runArray
.NSInteger
over regular int
, NSInteger
will give you the appropriate size for whatever architecture your app is running on.[runInfoDict setValue:[NSNumber numberWithInt:numbOfDate]...
by simply writing [runInfoDict setValue:@(numbOfDate) ...
, which will put the value into NSNumber
for you.