我有两个多对多关系的实体,父母 - >儿童。 Child实体有一个布尔属性,可以是TRUE或FALSE。
我可以很容易地计算[parent.child count]
有多少子实体,它为我返回一个很好的整数。
但是,如果我只想计算真实的子实体呢?有一个简单的方法吗?
我试图实现@unforgiven的谓词选择,但我得到了'无法解析格式字符串'错误 - 这是我正在尝试的代码(其中Checklist
是父实体, ChecklistItem
是子实体,checked
是ChecklistItem的bool值:
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
Checklist *aChecklist = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = aChecklist.name;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Checklist" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SUBQUERY(checklistItem, $sub, $sub.checked == %@).@count", [NSNumber numberWithBool:YES]];
[fetchRequest setPredicate:predicate];
NSError *error = nil;
NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
cell.detailTextLabel.text = [NSString stringWithFormat:@"%i items ticked", [results count]];
[fetchRequest release];
}
如果我用any self.checklistItems.checked = %@
替换谓词,应用程序不会崩溃,但返回的数字是检查了任何ChecklistItem的检查表总数,这显然意味着它返回每个清单都有相同的编号。
答案 0 :(得分:2)
尝试仅获取已检查对象的子集
NSPredicate *filterPredicate = [NSPredicate predicateWithFormat:@"checked = YES"]
NSSet *checkedChildren = [parent.children filteredSetUsingPredicate:filterPredicate];
NSUInteger count = [checkedChildren count];
今天在写出来之前没有仔细检查过,但我在很多场合都写过类似的代码。
为了清晰起见,划出三条线。
答案 1 :(得分:0)
您需要在Core数据中使用子查询。假设子实体具有名为booleanAttribute的布尔属性,您需要使用类似于以下谓词的东西从父实体获取对象:
NSPredicate *predicate = [NSPredicate predicateWithFormat: @"SUBQUERY(child, $sub, $sub.booleanAttribute == %@).@count", [NSNumber numberWithBool:YES]];
答案 2 :(得分:0)
我想出了另一种方法。我只是向我的父实体(“Checklist”)添加了一个名为“numberChecked”的整数属性,每次勾选或取消勾选ChecklistItem时,我都会从numberChecked中添加或删除一个。
if ([aChecklistItem checked] == [NSNumber numberWithBool:YES]) {
NSNumber *newCheckedNumber = [NSNumber numberWithFloat:[aChecklistItem.checklist.numberChecked floatValue] +1];
aChecklistItem.checklist.numberChecked = newCheckedNumber;
}
else if ([aChecklistItem checked] == [NSNumber numberWithBool:NO]) {
NSNumber *newCheckedNumber = [NSNumber numberWithFloat:[aChecklistItem.checklist.numberChecked floatValue] -1];
aChecklistItem.checklist.numberChecked = newCheckedNumber;
}
这很有效,但我仍然有兴趣知道是否有人可以想到一种方法,而不必明确地将其添加到我的数据模型中。
答案 3 :(得分:0)
几年后,现在这是一个简单的方法。
您可以使用@sum collection operator轻松计算集合中具有YES BOOL值的对象。
[parent valueForKeyPath:@"children.@sum.checked"];