Objective C - 将对象数组(带有日期字段)转换为数组字典(按星期键入)

时间:2010-01-25 14:12:25

标签: iphone objective-c date sorting nsdictionary

我有一个DiaryEntry对象的NSArray,其中每个DiaryEntry都有一个NSDate date_字段。

我想在表格视图中显示所有DiaryEntrys,按星期几分组, 其中每个组按日期按升序排序。

所以,我需要使用NSArray,并转换为数组的NSDictionary,其中键是星期几(NSDate),值是DiaryEntrys的NSArray,由date_字段按升序排序

我认为这是一个非常常见的操作,但无法在任何地方找到任何示例代码。

非常感谢任何帮助。

谢谢!

4 个答案:

答案 0 :(得分:1)

好吧,我假设你的DiaryEntry有一个日期属性。这是一个快速而肮脏的版本,你可以让它变得更好。

NSMutableDictionary *map = [[[NSMutableDictionary alloc] init] autorelease];
NSMutableArray *array;
for (DiaryEntry *entry in myArray) {
    array = [map objectForKey:entry.date];
    if (!array) {
        array = [[[NSMutableArray alloc] init] autorelease];
        [map setObject:array forKey:entry.date];
    }
    [array addObject:entry];
}

我会仔细检查方法名称/编译的代码......我在这里有点啰嗦,但它基本上是:

浏览列表。对于您找到的每个条目,查看是否存在与该日期关联的数组。如果没有,请创建它。添加到该阵列。

注意您可能需要考虑将结构更改为数组...除非您居住在超过7天的土地上,否则您可以存储按特定顺序存储的数组。我尽量避免地图结构,除非我有大量的对象,我想快速查找。

答案 1 :(得分:1)

以下应该有效(实际上没有编译和测试代码)

            NSEnumerator* enumerator;
            DiaryEntrys* currEntry;
            NSMutableDictionary* result;

            /*
             use sorting code from other answer, if you don't sort, the result will still contain arrays for each day of the week but arrays will not be sorted
             */
            [myArray sortUsingDescriptors:....];
            /*
             result holds the desired dictionary of arrays
             */
            result=[[NSMutableDictionary alloc] init];
            /*
             iterate throught all entries
             */
            enumerator=[myArray objectEnumerator];
            while (currEntry=[enumerator nextObject])
            {
                NSNumber* currDayOfTheWeekKey;
                NSMutableArray* dayOfTheWeekArray;
                /*
                 convert current entry's day of the week into something that can be used as a key in an dictionary
                 I'm converting into an NSNumber, you can choose to convert to a maningfull string (sunday, monday etc.) if you like
                 I'm assuming date_ is an NSCalendarDate, if not, then you need a method to figure out the day of the week for the partictular date class you're using

                 Note that you should not use NSDate as a key because NSDate indicates a particular date (1/26/2010) and not an abstract "monday"
                 */
                currDayOfTheWeekKey=[NSNumber numberWithInt:[[currEntry valueForKey:@"date_"] dayOfWeek]];
                /*
                 grab the array for day of the week using the key, if exists
                 */
                dayOfTheWeekArray=[result objectForKey:currDayOfTheWeekKey];
                /*
                 if we got nil then this is the first time we encounter a date of this day of the week so
                 we create the array now
                 */
                if (dayOfTheWeekArray==nil)
                {
                    dayOfTheWeekArray=[[NSMutableArray alloc] init];
                    [result setObject:dayOfTheWeekArray forKey:currDayOfTheWeekKey];
                    [dayOfTheWeekArray release];    // retained by the dictionary
                }
                /*
                 once we figured out which day the week array to use, add our entry to it.
                 */
                [dayOfTheWeekArray addObject:currEntry];
            }

答案 2 :(得分:0)

我没有对它进行测试,但我可以编写这段代码,您可以根据需要进行改进。


// Ordering the array ascending
            myArray = [myArray sortedArrayUsingDescriptors:
                                [NSArray arrayWithObject: 
                                 [[[NSSortDescriptor alloc] initWithKey:@"date_ field"
                                                              ascending:YES
                                                               selector:@selector(compare:)] autorelease]]];

            NSMutableDictionary *myDictionary = [[NSMutableDictionary alloc] init];
            NSMutableArray *arrayForCurrentDate = [[NSMutableArray alloc] init];
            NSString *lastDate = [myArray objectAtIndex:0];
            for (int i=0; i< [myArray count]; i++)
            {
                if (![lastDate isEqualToString:[myArray objectAtIndex:i])
                {
                    if ([arrayForCurrentDate count])
                        [myDictionary setObject:arrayForCurrentDate forKey:lastDate];
                    [arrayForCurrentDate removeAllObjects];
                    lastDate [myArray objectAtIndex:i];
                }
                [arrayForCurrentDate addObject:];
            }
            if ([arrayForCurrentDate count])
                  [myDictionary setObject:arrayForCurrentDate forKey:lastDate];

干杯,
VFN

答案 3 :(得分:0)

所以,这是我的最终结果。实际上,我不得不按天和月打包我的物品,而不是仅仅按星期几(在原始帖子中不清楚):

(条目是原始数组)

// reverse sort of entries, and put into daily buckets
-(NSMutableArray*) sortedEntries {  
    if (sortedEntries == nil) {
        NSInteger currentDay = -1;
        NSCalendar *gregorian = [NSCalendar currentCalendar];
        NSEnumerator* enumerator = [self.entries reverseObjectEnumerator];
        sortedEntries = [NSMutableArray new];
        DiaryEntry* currentEntry;
        while (currentEntry=[enumerator nextObject])
        {
            NSDate* date = [currentEntry valueForKey:@"date"];
            NSDateComponents *weekdayComponents = [gregorian components:(NSDayCalendarUnit | NSWeekdayCalendarUnit) fromDate:date];

            NSInteger newDay = [weekdayComponents day];
            if (currentDay == -1 || newDay != currentDay){
                NSMutableArray* dailyArray = [NSMutableArray new];  
                [sortedEntries addObject:dailyArray];
                [dailyArray addObject:currentEntry];
                [dailyArray release];

            } else {
                [[sortedEntries lastObject] addObject:currentEntry];
            }

            currentDay = newDay;
        }
    }

    return sortedEntries;
}