核心数据过滤

时间:2013-04-08 23:44:35

标签: ios objective-c core-data

我有一个核心数据结构如下:

Business <-------->> Employee <-------->> Address

每个企业都有多名员工,每个员工可以拥有多个地址。

在Business对象中,我希望能够获得指定特定条件的所有NSArray个对象的NSSetAddress。例如。所有街道名称都必须是唯一的。

我知道我可以覆盖isEqual:,但我猜这会产生意想不到的结果。否则,我一直在考虑使用valueForKeyPath:@"@distinctUnionOfObjects",但我认为我不能通过条件。

以下是我目前的一些代码:

    NSMutableArray *addressArray = [NSMutableArray array];
    NSArray *employees = [Employee sortedArray];

    //loop through employees
    for (Employee *employee in employees) {
        for (Address *address in employee.addresses) {
            [addressArray addObject:address];
        }
    }

    //filter out duplicates
    addressArray = [addressArray valueForKeyPath:@"@distinctUnionOfObjects.city"];

此代码为我提供了一个唯一城市的列表,但是,我想要一个包含Address个对象的集合,这些对象具有唯一的city值(或其他条件)。

2 个答案:

答案 0 :(得分:0)

我找到了使用LinqToObjectiveC library

执行此操作的方法
NSArray* addressesWithUniqueCities = [input distinct:^id(id address) {
    return [address city];
}];

查看源代码,底层实现如下:

typedef id (^Selector)(id item);

-(NSArray *)distinct:(Selector)keySelector
{
    NSMutableSet* keyValues = [[NSMutableSet alloc] init];
    NSMutableArray* distinctSet = [[NSMutableArray alloc] init];
    for (id item in self) {
        id keyForItem = keySelector(item);
        if (![keyValues containsObject:keyForItem]) {
            [distinctSet addObject:item];
            [keyValues addObject:keyForItem];
        }
    }
    return distinctSet;
 }

我的最终代码最终成为:

    NSMutableArray *addressArray = [NSMutableArray array];
    NSArray *employees = [Employee sortedEmployees];

    //loop through employees
    for (Employee *employee in employees) {
        for (Address *address in employee.addresses) {
            [addressArray addObject:address];
        }
    }

    //filter out duplicates
    NSArray *distinctAddressArray = [addressArray distinct:^id(id address) {
        return [address addressLine];
    }];

    return distinctAddressArray;

答案 1 :(得分:0)

我不确定这是你的意思,但你可以尝试类似:(未经测试)

+ (NSMutableArray*) addressesForBusiness:(Business*)business
                         sectionProperty:(NSString*)sectionProperty
{

    NSFetchRequest* request = [[NSFetchRequest alloc] initWithEntityName:@"Address"];
    request.predicate = [NSPredicate predicateWithFormat:@"employee.business == %@",business.objectID];
    request.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:sectionProperty ascending:YES]];

    NSArray* addresses = [business.managedObjectContext executeFetchRequest:request error:NULL];
    NSMutableArray* sections = [NSMutableArray new];
    NSMutableArray* currentSection = [NSMutableArray new];
    NSManagedObject* prevAddress = nil;
    for (NSManagedObject* address in addresses) {
        if (prevAddress && ([[address valueForKey:sectionProperty] isEqual:[prevAddress valueForKey:sectionProperty]])) {
            currentSection = [NSMutableArray new];
            [sections addObject:currentSection];
        }
        prevAddress = address;
        [currentSection addObject:address];
    }

    return sections;
}

这将返回一个数组数组,其中每个内部数组都保存具有相同属性值的对象。在您的示例中,您可以打电话:

[[self class] addressesForBusiness:someBusiness sectionProperty:addressLine];