计算核心数据中的不同项目

时间:2011-11-03 16:04:36

标签: iphone objective-c ios core-data nsfetchrequest

我有一个Core Data实体,其名称为'value',经常重复。我希望只检索唯一值(完成)以及每个值出现的频率,以便我可以按该属性排序(我正在根据现有用户输入构建自动完成功能,因此知道某个输入出现的频率是多少必要的)。

我的抓取请求目前如下所示:

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 个答案:

答案 0 :(得分:1)

我不喜欢这个,但是......
您可以使用与您正在寻找的值完全匹配的谓词执行其他fetchRequest。允许重复,然后计算数组。

这个更好,但前面有更多的工作 另一种方法是在数据模型中具有派生属性,以便在创建时跟踪重复计数。 (使用该选项,您可以轻松按重复计数排序)


确定Derived属性。 首先,您需要子类化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号(它看起来很简单),但我从未做过类似的事情。所以我不确定核心数据中类变量的预定。