2013-04-08 106 views
0

我有一個核心數據結構如下:核心數據過濾

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

每個企業都有多個員工和每個員工可以有多個地址。

從Business對象中,我希望能夠獲得指定特定條件的所有Address對象中的NSArrayNSSet。例如。所有的街道名稱都必須是唯一的。

我知道我可以覆蓋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值(或其他一些條件的集合)。

+0

問題是沒有獨特的解決方案。如果同一城市有多個地址,應選擇哪個地址對象?下面的解決方案選擇「第一個」,這是隨機的,因爲數組中的對象沒有明確定義的順序。 – 2013-04-09 05:12:03

+0

的確如此。我用這個簡單的例子。我有一個基於其他一些屬性生成的自定義屬性。在我的情況下,第一個是好的,但我用它作爲基於屬性過濾唯一對象的簡單示例。 – danielbeard 2013-04-09 05:18:47

回答

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; 
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]; 
相關問題