views:

37

answers:

1

Hey guys,

I'm very new to iphone development, so you'll have to forgive me.

So currently I have a table that displays messages, but I'd like to group the messages by date, e.g.

Tuesday 4/5/98 //header


message 1

message 2

message 3

Wednesday 4/6/98


message 1

etc.

So right now, it's just one long NSMutableArray oldArr (sorted).

What I was thinking of doing, was creating another NSMutableArray (groupArr) of unique date objects (DateGroup), in which each DateGroup would have the following ivars:

int size; //number of messages for date
int index; //index of first message in the total array
//so I can easily retrieve the object when the section and row is asked
NSDate date; //need the date for the header

With these ivars, I can get all the sections with groupArr size, all the individual row sizes by accessing the DateGroup size, and the individual cell when given a section, row arguments by getting the index + row.

I think this is the best way to do it. However, I am having problems populating the groupArr from the oldArr (which will dynamically increase in size). I was thinking of going one by one through the oldArr with this psuedocode:

NSDate date = nil;
int size = 1;
int index = 0;
for (int i = 0; i < oldArr.size; i++) {
OldGroup* cur = [oldArr objectAt:i];
if (date is different from cur->date){ //i know, it's pseudocode
DateGroup* newGroup = [[DateGroup alloc] initWithDate:cur->date index:index];
[groupArr add:NewGroup];
date = cur->date;
index += size;
size = 1;
} else{ //the date is the same, so the object belongs in the group
[groupArr lastObject].size++;
}
}

I apologize for the messy code, I don't know how to format it in Stack Overflow.

Anyway, while I think this will work, it seems very unelegant to me. I was thinking about using the "indexOfObjectPassingTest" of NSMutableArry to find the next date, but can't seem to implement it conceptually. I'm trying to design a good way to do this. Any suggestions?

Thanks and I apologize for the confusing ideas here.

A: 

I haven't even compiled this so beware of errors and leaks, and it is perhaps not the most efficient way. But I think you can use the NSDateFormatter to chop the time component that you don't care about when sorting dates into groups. The result is an array of groups with each group being an array of your events, sorted into dates. Then you just need a sort predicate to arrange it in the order you choose to display it and it's ready for the UITableView.

- (void)addDatedEvent:(MyEventClass*)newEvent ToGroup:(NSMutableArray*)dateGroups 
{
  NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
  [dateFormatter setTimeStyle:NSDateFormatterNoStyle];
  [dateFormatter setDateStyle:NSDateFormatterMediumStyle];

  NSDate* eventDate = newEvent.evDate;
  NSString* dateString = [dateFormatter stringFromDate:eventDate];

  BOOL added = NO;
  for(NSMutableArray* group in dateGroups)
  {
    MyEventlass* firstEvent = [group objectAtIndex:0];
    NSDate* firstEventDate = firstEvent.evDate;
    NSString* firstEventDateString = [dateFormatter stringFromDate:firstEventDate];

    if([firstEventDateString isEqualToString:dateString])
    {
      // match - this event joins others in an existing group
      [group addObject:newEvent];
      added = YES;
    }
  }

  if(added == NO)
  {
    // need to create a new group since this is the first date
    NSMutableArray* newGroupArray = [NSMutableArray arrayWithObject:newEvent];
    [dateGroups addObject:newGroupArray];
  }
}
Adam Eberbach
Cool Thanks for the time and effort, Adam! Yeah, you're approach is very similar to mine--going through each date to see if it belongs. However, I see that you actually add the whole message/"event" to the group, which is actually very interesting, albeit space costly. However, I am already provided with a sorted message array, so there really is no need to go one by one through the array since it will always go to the last one. That way does simplify it a lot, though.
I was imagining it in the context of something I once did. Hope it helped. Would it really be costly in terms of space? The array stores a pointer to the MyEventClass object, it doesn't have to have a copy.
Adam Eberbach
Yeah, it's not horrible. But I could imagine 500 messages being costly. My original idea was to only keep the necessary info for each unique date, but your implementation seems a lot more intuitive. I decided to go with a variation of this one (hashing it by date instead of looking through each one). Thanks!