我有一个NSDictionary集合,其键是一个唯一的id,value是一个包含两个不同对象的数组(FruitClass,ProductClass),我想将该集合分组,使其先由ProductClass.productName排序,然后由FruitClass排序。项目名称。
所以最终的列表看起来像是:
{apple, butter}
{apple, pie}
{banana, daiquiri}
{banana, smoothie}
{melon, zinger}
其中第一项是FruitClass实例项,第二项是ProductClass实例项。
这样做的最佳方法是什么?我遇到的大多数例子都是在一个键上完成的。如何使用具有2种不同对象类型的NSDictionary来完成它?
查看NSDictionary的keysSortedByValueUsingSelector,
- (NSArray *)keysSortedByValueUsingSelector:(SEL)comparator
我得到的印象是你会在值对象的类类型上创建'compare'方法。因此,对于多字段排序,我是否必须求助于创建一个新的对象类型,'CombinedClass',其中包含FruitClass& ProductClass并实施'比较'来实现这一目标?
FruitClass:
{
NSString *itemName;
}
@end
@interface ProductClass
{
NSString *productName;
}
@end
答案 0 :(得分:1)
如果数据结构只包含一个水果而且只包含一个产品,则数组不是一个好选择。您可以使用另一个类并提供compare:
比较器:
@interface ComboClass : NSObject
{
FruitClass *fruit;
ProductClass *product;
}
@property(nonatomic,retain) FruitClass *fruit;
@property(nonatomic,retain) ProductClass *product;
- initWithFruit:(FruitClass *)f andProduct:(ProductClass *) p;
@end
@implementation ComboClass
@synthesize fruit;
@synthesize product;
- (void) dealloc
{
[fruit release];
[product release];
[super dealloc];
}
- initWithFruit:(FruitClass *)f andProduct:(ProductClass *) p
{
self = [super init];
if (!self) return nil;
self.fruit = f; // some recommend against accessor usage in -init methods
self.product = p;
return self;
}
- (NSComparisonResult) compare:(id) another
{
NSComparisonResult result = [self.fruit.itemName compare:another.fruit.itemName];
if (result == NSOrderedSame)
return [self.product.productName compare:another.product.productName];
else
return result;
}
@end
或者,您可以使用带有product
和fruit
键值对的NSDictionary(因此您最终会在字典中使用字典)。 NSSortDescriptor
类可用于使用键路径的值对数组进行排序,因此可能是另一种探索选项。
答案 1 :(得分:-1)
你的比较器可以对你投掷的任何东西起作用......你可以将它的两个参数 s 视为NSArray对象 s ,如果这是你需要的。当您将数组作为值放入字典时,只需使用它们 - 不需要其他类。
如果你想建立一个新的课程(可能出于设计原因) - 去吧,但这不是“必须做的”。
编辑:删除以明确只给出一个参数 - 另一个是调用选择器的对象。使用NSArray需要类扩展,自定义类更清晰。
答案 2 :(得分:-1)
您可以向NSArray添加一个可以进行比较的类别,而不必创建另一个类。
@interface NSArray ( MySortCategory )
- (NSComparisonResult)customCompareToArray:(NSArray *)arrayToCompare;
@end
根据您的描述,实施应该非常简单。
编辑我有点恼火的是,这个标记没有评论,所以我做了一个完整的实施,以确保它可以工作。这与您的样本略有不同,但想法相同。
FruitsAndProducts.h
@interface Fruit : NSObject
{
NSString *itemName;
}
@property(nonatomic, copy)NSString *itemName;
@end
@interface Product : NSObject
{
NSString *productName;
}
@property(nonatomic, copy)NSString *productName;
@end
FruitsAndProducts.m
#import "FruitsAndProducts.h"
@implementation Fruit
@synthesize itemName;
@end
@implementation Product
@synthesize productName;
@end
的NSArray + MyCustomSort.h
@interface NSArray (MyCustomSort)
- (NSComparisonResult)customCompareToArray:(NSArray *)arrayToCompare;
@end
的NSArray + MyCustomSort.m
#import "NSArray+MyCustomSort.h"
#import "FruitsAndProducts.h"
@implementation NSArray (MyCustomSort)
- (NSComparisonResult)customCompareToArray:(NSArray *)arrayToCompare
{
// This sorts by product first, then fruit.
Product *myProduct = [self objectAtIndex:0];
Product *productToCompare = [arrayToCompare objectAtIndex:0];
NSComparisonResult result = [myProduct.productName caseInsensitiveCompare:productToCompare.productName];
if (result != NSOrderedSame) {
return result;
}
Fruit *myFruit = [self objectAtIndex:1];
Fruit *fruitToCompare = [arrayToCompare objectAtIndex:1];
return [myFruit.itemName caseInsensitiveCompare:fruitToCompare.itemName];
}
@end
这里正在行动
// Create some fruit.
Fruit *apple = [[[Fruit alloc] init] autorelease];
apple.itemName = @"apple";
Fruit *banana = [[[Fruit alloc] init] autorelease];
banana.itemName = @"banana";
Fruit *melon = [[[Fruit alloc] init] autorelease];
melon.itemName = @"melon";
// Create some products
Product *butter = [[[Product alloc] init] autorelease];
butter.productName = @"butter";
Product *pie = [[[Product alloc] init] autorelease];
pie.productName = @"pie";
Product *zinger = [[[Product alloc] init] autorelease];
zinger.productName = @"zinger";
// create the dictionary. The array has the product first, then the fruit.
NSDictionary *myDict = [NSDictionary dictionaryWithObjectsAndKeys:[NSArray arrayWithObjects:zinger, banana, nil], @"zinger banana", [NSArray arrayWithObjects:butter, apple, nil], @"butter apple", [NSArray arrayWithObjects:pie, melon, nil], @"pie melon", nil];
NSArray *sortedKeys = [myDict keysSortedByValueUsingSelector:@selector(customCompareToArray:)];
for (id key in sortedKeys) {
NSLog(@"key: %@", key);
}