Базовые данные: получить объекты с наибольшим значением в каждой категории - PullRequest
0 голосов
/ 07 июля 2011

В настоящее время я борюсь с реализацией основных данных, чтобы получить эффект «лучшая в каждой категории» - я уже довольно долго пытаюсь найти решение, и просто не могу найти правильный подход <. <</p>

У меня есть три подкласса NSManagedObjects, давайте назовем их «Person», «Child» и «School» для объяснения причин.У каждого человека может быть несколько детей, поэтому между этими сущностями существует множество отношений: Лицо <--- >> Ребенок

Ребенок посещает школу, в одной школе много детей, поэтому у нас есть: Ребенок <<---> Школа

С этой структурой данных я хочу получить список детей , структурированный с такими условиями:

  1. детей в спискедолжен соответствовать определенным требованиям (например, возраст, посещать определенную школу, ...) (легко выполняется с помощью NSPredicate)
  2. список отсортирован по оценкам детей (или как вам угодно, только атрибут)
  3. учитывается только самый лучший ребенок каждого родителя , который соответствует требованиям (в 1.)!

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

Было быбыть оптимальным, чтобы обернуть его в NSFetchedResultsController, чтобы этот список можно было легко отобразить с помощью UITableView.

Но каков наилучший подход?Можно ли это сделать с помощью соответствующего предиката?Я очень ценю вашу помощь!

:)

РЕДАКТИРОВАТЬ: Проблема была решена с помощью следующего решения (которое не совсем оптимально, когда речь идет о производительности, но оно делает свою работу =) Я заменилимена сущностей с теми, которые используются в объяснении выше.)

Лично.м .:

- (NSArray *)bestChildrenWithPredicate:(NSPredicate *)aPredicate {    // create request

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Child" inManagedObjectContext:moc]];
// set predicate to fetch only children of current person and those that fit in the given predicate (possible to get back children of multiple schools)
NSPredicate *thePredicate = [NSPredicate predicateWithFormat:@"parent == %@",self];
if (aPredicate) thePredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:thePredicate, aPredicate, nil]];
[request setPredicate:thePredicate];
// sort results for grade and execute request
[request setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"grade" ascending:YES]]];
NSError *error = nil;
NSArray *sortedResultsForPredicate = [moc executeFetchRequest:request error:&error];
[request release];
if (!sortedResultsForPredicate) {
    // handle error
    abort();
}
// create dictionary with schools as keys
NSMutableDictionary *bestResults = [[[NSMutableDictionary alloc] init] autorelease];
// loop through all results
for (Child *aResult in sortedResultsForPredicate) {
    // get string for dictionary index
    NSString *theSchoolKey = aResult.school.key;
    // check if the school already exists in the dictionary
    if (![bestResults objectForKey:theSchoolKey]) {
        [bestResults setObject:aResult forKey:theSchoolKey];
    } else {
        // get the current result
        Result *preResult = [bestResults objectForKey:theSchoolKey;
        // compare the results by grade and replace if new one is better
        NSComparisonResult comp = [preResult compareByGrade:aResult];
        if (comp==NSOrderedDescending||(comp==NSOrderedSame&&[[aResult valueForKey:@"date] compare:[preResult valueForKey:@"date"]]==NSOrderedAscending)) {
            [bestResults setObject:aResult forKey:theSchoolKey];
        }
    }
}
// return best graded children of each school sorted by date
return [[bestResults allValues] sortedArrayUsingSelector:@selector(compareByDate:)];

}

1 Ответ

1 голос
/ 07 июля 2011

Если вы храните своих родителей в отдельном объекте и имеете отношения в дочернем объекте, то вы должны иметь возможность перебирать список родителей, извлекать только дочерние элементы для этого родителя, считывать результаты в отсортированный массив ивытолкнуть последнее значение, используя [myArray lastResult];Затем вы добавили бы этот объект в изменяемый массив, к которому вы могли бы обращаться в вашем приложении.У меня пока нет времени поместить его в код, но основы будут такими:

Fetch the parents entity into an array
Iterate the parents array, using the parent as the constraint for the child entity, and        use NSSortDescriptor initWithKey:@"grade" (or whatever you call it) ascending:YES. 
Read the results into a resultsArray
id bestKid = [resultsArray lastObject];
[myNSMutableArray addObject:bestKid];

Сделайте это для каждого родительского объекта, и тогда myNSMutableArray будет содержать массив лучших записей о детях.

Теперь я лучше знаком с прямым SQL, чем с Core Data, поэтому приветствую исправление, если это решение неосуществимо!:)

...