0

次のようなコアデータ構造があります。

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

各企業には複数の従業員がおり、各従業員は複数の住所を持つことができます。

Business オブジェクトから、特定の条件を指定するすべてのオブジェクトのNSArrayorを取得できるようにしたいと考えています。たとえば、通りの名前はすべて一意である必要があります。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

4

2 に答える 2

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];
于 2013-04-09T18:51:34.453 に答える
0

LinqToObjectiveC ライブラリでこれを行う方法を見つけました。

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;
于 2013-04-08T23:55:45.813 に答える