2009-12-07 94 views
1

我有一個不尋常的問題,我有一個水果名單(蘋果,橙,香蕉,葡萄等)。它們可以組織成小組,例如:在Obj-c中組織一組的最佳方式是什麼?

Group 1: apple, green_apple, pineapple 
Group 2: grapes, banana, strawberries, apple 
Group 3: orange, grapes, green_apple 

然後,每個組都與價格相關聯。因此,組1 - > 9.99,組2 - > 15.99等

然後稍後當給出一個列表,他們需要匹配現有的組,如果沒有找到,創建一個。如果存在,則返回價格。

這樣做的最好方法是什麼?基本上這個關聯需要是一個NSDictionary,但是關鍵看起來應該是一個數組。那麼問題是,如何在輸入一些信息時構造密鑰?我必須求助於按字母順序排列鍵,以使鍵保持一致?但是當名稱包含符號($ apple等)時,這種方法不會太好。

你的方法是什麼?

回答

3

使用NSSet而不是NSArray(集合是無序列表,它聽起來就是你在這裏得到的)。但是,我不確定NSDictionary在確定密鑰時將使用[NSSet isEqualToSet:](或其他所謂的方法)方法而不是指針相等,因此您可能必須實現自己的密鑰檢查方法。

1

好像你可以使用NSSet中作爲關鍵的NSDictionary:

NSMutableDictionary * dict = [NSMutableDictionary dictionary]; 

NSSet * set; 
set = [NSSet setWithObjects:@"a", @"b", @"c", @"d", nil]; 
[dict setObject:@"1" forKey:set]; 

set = [NSSet setWithObjects:@"b", @"c", @"d", @"e", nil]; 
[dict setObject:@"2" forKey:set]; 

id key; 
NSEnumerator * enumerator = [dict keyEnumerator]; 
while ((key = [enumerator nextObject])) 
    NSLog(@"%@ : %@", key, [dict objectForKey:key]); 

set = [NSSet setWithObjects:@"c", @"b", @"e", @"d", nil]; 
NSString * value = [dict objectForKey:set]; 
NSLog(@"set: %@ : key: %@", set, value); 

輸出:

2009-12-08 15:42:17.885 x[4989] (d, e, b, c) : 2 
2009-12-08 15:42:17.887 x[4989] (d, a, b, c) : 1 
2009-12-08 15:42:17.887 x[4989] set: (d, e, b, c) : key: 2 

另一種方法是使用NSMutableDictionary持有多個NSSet「項目和價格第作爲一個關鍵,但是注意到,如果價格不是唯一的,這將不起作用。

您可以手動檢查集合是否在字典中,通過遍歷項目和每個集合使用isEqualToSet: - 除非任何人都能想出更好的方法。

如果您返回的價格(關鍵),如果它不是你可以用一個價格,主要部件插入:

@interface ShoppingList : NSObject 
{ 
    NSMutableDictionary * shoppingList; 
} 

- (void)setList:(NSSet*)aList 
     forPrice:(double)aPrice 
{ 
    [shoppingList setObject:aList forKey:[NSNumber numberWithDouble:aPrice]]; 
} 

- (double)priceForList:(NSSet*)aList 
{ 
    id key; 
    NSEnumerator * enumerator = [shoppingList keyEnumerator]; 
    while ((key = [enumerator nextObject])) 
    { 
     NSSet * list = [shoppingList objectForKey:key]; 

     if ([aList isEqualToSet:list]) 
     { 
      return [(NSNumber*)key doubleValue]; 
     } 
    } 

    return 0.0; 
} 

{ 
    ShoppingList * shoppingList = [[ShoppingList alloc] init]; 

    NSSet * list; 
    double price = 0.0; 

    list = 
     [NSSet setWithObjects:@"apple",@"green_apple",@"pineapple",nil]; 
    [shoppingList setList:list forPrice:9.99]; 

    list = 
     [NSSet setWithObjects:@"grapes",@"banana",@"strawberries",@"apple",nil]; 
    [shoppingList setList:list forPrice:15.99]; 

    list = 
    [NSSet setWithObjects:@"orange",@"grapes",@"green_apple",nil]; 
    [shoppingList setList:list forPrice:7.50]; 

    // searching for this 
    list = 
     [NSSet setWithObjects:@"grapes",@"banana",@"strawberries",@"apple",nil]; 

    price = [shoppingList priceForList:list]; 
    if (price != 0.0) 
    { 
     NSLog(@"price: %.2f, for pricelist: %@", price, list); 
    } 
    else 
    { 
     NSLog(@"shopping list not found: %@", list); 
     [shoppingList setList:list forPrice:15.99]; 
    } 
} 
+0

但是如果價格不是唯一的呢? – erotsppa 2009-12-07 13:59:46

+0

然後將對象存儲在NSMutableSets中,而不是使用相同的價格檢查添加新的集合,以查看是否存在具有該價格的集合,並在其中添加對象。 – 2009-12-07 17:04:25

+0

所有我能想到的情況下,價格不唯一的情況是創建記錄,無論是NSSet的自定義類或NSDictionary,項目列表和價格,並且對於密鑰,您可以使用類似唯一id(int)的內容。 – stefanB 2009-12-07 19:57:32

0

您可以使用簡單e CoreData解決方案,從長遠來看,它可能是最簡單的。對於你的場景,你可以創建兩個實體,比如說ItemPriceGroupItem實體可以具有name屬性和一對一的關係。 PriceGroup實體可能具有description屬性(儘管在您的方案中它甚至不需要該屬性),price屬性和多對多關係。假設你建立這兩個,簡單的實體,並得到一個情況下,你可以輕鬆地創建社團,像這樣的代碼:

- (void)createGroup:(NSNumber*)price withProducts:(NSSet*)productNames 
{ 
    // assume context exists and was retrieved from somewhere 
    NSManagedObject* priceGroup = [NSEntityDescription insertNewObjectForEntityForName:@"PriceGroup" inManagedObjectContext:context]; 
    [priceGroup setValue:price forKey:@"price"]; 

    for(NSString* productName in productNames) { 
    NSManagedObject* product = [NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext:context]; 
    [product setValue:productName forKey:@"name"]; 
    [product setValue:priceGroup forKey:@"priceGroup"]; 
    } 
} 

現在你會與你的價格組相關聯的所有產品在你的管理對象上下文。這意味着您可以對它們進行各種查詢,輕鬆地對它們進行排序等。

作爲另一個示例,以下是如何獲取組價格超過9.99美元的所有商品,而不是某些特定組(例如, $ 15.99售價組):

- (NSSet*)itemsAsDescribed 
{ 
    // Get this from somewhere 
    NSManagedObjectContext* context = /* get this or set this */ 
    NSManagedObject* exclusionGroup = /* get this or set this */ 
    NSFetchRequest* request = [[[NSFetchRequest alloc] init] autorelease]; 
    NSPredicate* predicate = [NSPredicate predicateWithFormat:@"priceGroup.price >= 9.99 AND NOT SELF in %@", [exclusionGroup valueForKey:@"items"]]; 
    [request setEntity:[NSEntityDescription entityForName:@"Item" inManagedObjectContext:context]]; 
    [request setPredicate:predicate]; 
    NSError* error = nil; 
    NSSet* results = nil; 
    NSArray* array = [context executeFetchRequest:request error:&error]; 
    if(!array) { 
    // handle the error 
    } else { 
    results = [NSSet setWithArray:array]; 
    } 
    return results; 
} 

在這種情況下,由於不會有太多的一對多的關係,具有集是不必要的,但是,如果你在未來改變它,這樣一個項目可以在多個組(如常規價格組和銷售價格組),這對於確保您的結果中沒有重複項目是必要的。

相關問題