views:

91

answers:

2

I have a plist which contains an array of NSDictionary 's which represent a certain event each dictionary contains a few pieces of information about the event and a NSDate with the date of the event e.g.

I wish to create a sectioned table view with this date very much like in the Calendar app which ships with the iPhone when you click on the "List" view. You can see there are only sections for the dates where there are events.

So whats the best way to find out to begin with how many NSDictionary 's have the same date (so I know how many sections to create and how many rows in each section, as each section will have a different amount or rows).

Thanks

+1  A: 

I did something very similar to this for Reconnected except my sections are for years (see the History screenshot).

  1. Sort the array by the date key.
  2. Start with the first item. The date of the first item represents the first segment. In my case, I only care about the year.
  3. Create an array for the section with the date. Add the currently inspected to the section's array. Add the section's array to another array that will be the array of all sections in your table.
  4. Move on to the next item. If the next item's date equals the previous item's date, add the current item to the current section's array. Otherwise, apply step #3 to the new date.
  5. Repeat the previous step for rest of the array from your plist.

At the end of step 5, you should have an array of sections. From that section you can send it a message for the number of NSDictionary's you've added to the section which will represent each rows in your table.

Giao
A: 

After a bit of playing around this is what I have come up with, at the moment its just a foundation tool to keep it clear.

#import <Foundation/Foundation.h>

NSDate* normalizedDateWithDate(NSDate *date) {
    NSCalendar *calendar = [NSCalendar currentCalendar];

    unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit;
    NSDateComponents *comp = [calendar components:unitFlags fromDate:date];

    return [calendar dateFromComponents:comp];
}


int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSString *plistPath = @"flights.plist";
    NSArray *array = [[NSArray alloc] initWithContentsOfFile:plistPath];
    NSMutableSet *flightDates = [[NSMutableSet alloc] init];

    for (NSDictionary *oneFlight in array) 
            [flightDates addObject:normalizedDateWithDate([oneFlight objectForKey:@"flightDate"])];

    NSLog(@"Number of Sections Required: %d", [flightDates count]);

    NSMutableDictionary *datesAndFlights = [[NSMutableDictionary alloc] init];



    for (NSDate *fDate in flightDates) {
        NSMutableArray *sectionFlights = [[NSMutableArray alloc] init];
        for (NSDictionary *oneFlight in array) {    
            if ([normalizedDateWithDate([oneFlight objectForKey:@"flightDate"]) isEqualToDate: normalizedDateWithDate(fDate)]) 
            {
                [sectionFlights addObject:oneFlight];
            }
        }
        [datesAndFlights setObject:sectionFlights forKey:normalizedDateWithDate(fDate)];
        [sectionFlights release];
    }


    NSEnumerator *enumerator = [datesAndFlights keyEnumerator];
    NSDate *key;

    while ((key = [enumerator nextObject])) {
        NSLog(@"Key: %@", key);
        for (NSDictionary *oneFlight in [datesAndFlights objectForKey:key]) {
            NSLog(@"flightNumber: %@ and Total Time: %@", [oneFlight objectForKey:@"flightNumber"], [oneFlight objectForKey:@"totalTime"]);
        }
    }

    [array release];
    [flightDates release];
    [datesAndFlights release];

    [pool drain];
    return 0;
}

This is just what I have managed to put together and it seems to work but if anyone can see a way to make this better or more concise please say so! Also the function at the top which I use to make sure the date is always at time 00:00:00 when I compare it I have seen the NSCalendar – rangeOfUnit:startDate:interval:forDate: method in the documentation does anyone know if its better to use this instead?

Thanks

Daniel Granger