Подсчет отдельных элементов в основных данных - PullRequest
0 голосов
/ 03 ноября 2011

У меня есть объект Core Data со свойством с именем 'value', которое часто повторяется.Я хочу получить только уникальные значения (готово), а также то, как часто каждое из них появляется, чтобы я мог сортировать по этому свойству (я строю функцию автозаполнения на основе существующего пользовательского ввода, поэтому знание того, как часто появлялся определенный ввод,essential).

Мой запрос на выборку сейчас выглядит следующим образом:

NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.managedObjectContext];
NSDictionary *entityProperties = [entity propertiesByName];
[fetchRequest setEntity:entity];

[fetchRequest setFetchBatchSize:10];
[fetchRequest setFetchLimit:20];
[fetchRequest setReturnsDistinctResults:YES];
[fetchRequest setResultType:NSDictionaryResultType];

[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:[entityProperties objectForKey:@"value"]]];

NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"value" ascending:YES] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"value BEGINSWITH[c] %@",predicateString];
[fetchRequest setPredicate:predicate];

return fetchRequest;

Я немного застрял в этом.Есть идеи?

Заранее спасибо!

1 Ответ

1 голос
/ 03 ноября 2011

Мне не нравится этот, но ...
Вы можете сделать другой fetchRequest с предикатом, который точно соответствует значению, которое вы ищете. Если разрешить дубликат, то есть счетчик массива.

Этот лучше , но впереди больше работы.
Другим способом может быть наличие в вашей модели данных производного свойства, которое будет отслеживать ваши дублированные значения при их создании. (с помощью этой опции вы можете легко отсортировать по дублированному количеству)


Хорошо для производного объекта. Сначала вам нужно будет создать подкласс NSManagedObject и использовать этот подкласс в вашей модели данных. (в Xcode 3 был способ создать это быстро, но я не знаю, что в Xcode 4) Но если вы назовете его таким же, как ваша сущность, я думаю, что основные данные его подберут.

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface Person : NSManagedObject 
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * firstLetterOfName;
@property (nonatomic, retain) NSString * phoneNumber;
@end

А в вашей реализации вам нужно будет сделать что-то вроде этого (в Xcode 4 есть фрагмент кода для начала работы, но в одном из них есть опечатка, если она не была исправлена)

#import "Person.h"
@implementation Person
@dynamic name, phoneNumber, firstLetterOfName;
- (void)setName:(NSString *)value {
[self willChangeValueForKey:@"name"];
[self setPrimitiveValue:value forKey:@"name"];
self.firstLetterOfName = [value substringToIndex:1];
[self didChangeValueForKey:@"name"];
}
@end

Вы можете видеть, что firstLetterOfName устанавливается каждый раз, когда задается Имя.
Вы можете сделать то же самое с отношениями. Поэтому, когда вы добавляете какой-либо элемент в отношения, вы сможете найти свои отношения.

Вот пример чего-то похожего, где мне нужно выяснить, имеет ли объект, который я добавляю, самую низкую цену своей группы из-за вызова производного свойства isMeilleurPrixAvecPrixElment. (это старый код, поэтому я не вспоминаю все его детали, это было сделано в OSX.4)

- (void)addPrixHistoriqueObject:(PrixElement_MO *)value
{   
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];

[self willChangeValueForKey:@"prixHistorique" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];

if ([self isPrixRegulierAvecPrixElement:value])
    [self enleveL_AutrePrixRegulierPourCommerceDeCePrixElement:value];

if ([self isMeilleurPrixAvecPrixElment:value])
    [self echangeMeilleurPrixAvecCePrixElement:value];

[[self primitivePrixHistorique] addObject:value];
[self didChangeValueForKey:@"prixHistorique" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];

[changedObjects release];
}

В ответ на комментарий

В зависимости от вашей модели данных и важности этого аспекта в вашем приложении, я могу придумать 3 решения.
1- Пересмотр вашей модели данных вокруг этого аспекта.
2- При установке значений запрашивайте остальную часть вашей сущности с помощью предиката и обновляйте свойство с количеством.
3- (я не уверен в этом, но стоит попробовать) NSManagedObect - это объект, поэтому, возможно, у вас может быть статический словарь, в котором значение является ключом, а количество - значением.

Возможно, я бы сначала попробовал номер 3 (похоже, что самый простой), но я никогда не делал ничего подобного. Поэтому я не уверен, что в базовых данных есть переменная класса.

...