Цель C - преобразовать массив объектов (с полем даты) в словарь массивов (с указанием дня недели) - PullRequest
2 голосов
/ 25 января 2010

У меня есть NSArray объектов DiaryEntry, где у каждого DiaryEntry есть поле даты NSDate.

Я хочу отобразить все DiaryEntrys в виде таблицы, сгруппированные по дням недели, где каждая группа отсортирована по дате в порядке возрастания.

Итак, мне нужно взять NSArray и преобразовать в NSDictionary массивов, где ключом является день недели (NSDate), а значением является NSArray для DiaryEntrys, упорядоченный полем date_ в порядке возрастания .

Я полагаю, что это довольно распространенная операция, но нигде не могу найти пример кода.

Любая помощь очень ценится.

Спасибо !!

Ответы [ 4 ]

1 голос
/ 26 января 2010

Следующее должно работать (на самом деле не компилировать и не тестировать код)

            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];
            }
1 голос
/ 25 января 2010

Ну, я предполагаю, что у вашего DiaryEntry есть свойство date. Вот быстрая и грязная версия, вы можете сделать это намного лучше.

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 дней, вы можете хранить массив, хранящийся в определенном порядке. Я стараюсь максимально избегать структур карты, если у меня нет тонны объектов, и я хочу быстрый поиск.

0 голосов
/ 01 февраля 2010

Итак, вот мой окончательный результат. На самом деле мне приходилось собирать свои объекты по дням и месяцам, а не только по дням недели (неясно в исходной публикации):

(записи являются исходным массивом)

// 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;
}
0 голосов
/ 25 января 2010

Я не тестировал его, но я мог написать этот фрагмент кода, который вы можете улучшить по мере необходимости.


// 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

...