我有一个不寻常的问题,我有一份水果清单(苹果,橙子,香蕉,葡萄等)。它们可以组织成小组,例如:
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等)时,这种方法不会太好。
你的方法是什么?
答案 0 :(得分:3)
使用NSSet
代替NSArray
(集合是无序列表,听起来就像你在这里得到的那样)。但是,在确定密钥时,我不确定NSDictionary
将使用[NSSet isEqualToSet:]
(或其所谓的)方法而不是指针相等,因此您可能必须实现自己的密钥检查方法。 / p>
答案 1 :(得分: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];
}
}
答案 2 :(得分:0)
你可以使用一个简单的CoreData解决方案,从长远来看,它可能是最简单的。对于您的方案,您可以创建两个实体,例如Item
和PriceGroup
。 Item
实体可以具有name
属性和一对一priceGroup
关系。 PriceGroup
实体可以具有description
属性(尽管在您的方案中,它甚至不需要),price
属性和多对多items
关系。假设你设置了这两个简单的实体,并获得了一个上下文,你可以在代码中轻松创建你的关联:
- (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;
}
在这种情况下,由于没有多对多的关系,因此,如果您将来更改它,那么项目可以在多个组中(如常规价格组和销售价格组),这是确保您没有在结果中获得重复项目的必要条件。