2013-02-03 47 views
4

我使用的NSSet以下星座:的NSSet使用词典:获取由值对象的关键

NSSet { 
    NSDictionary { 
     "Unique-Identifier-Key": Unique Value 
     "Key2": ValueABC 
     "Key3": ValueDEF 
    } 

    NSDictionary { 
     "Unique-Identifier-Key": Unique Value 
     "Key2": ValueFGH 
     "Key3": ValueJKL 
    } 

    NSDictionary { 
     "Unique-Identifier-Key": Unique Value 
     "Key2": ValueRST 
     "Key3": ValueXYZ 
    } 
} 

我在寻找一种方式来获得一个字典出的NSSet通过其独特的价值。 NSSet中有很多NSDictionaries,因此我正在寻找最佳性能的方式。

如何通过以下方式使用(NSSet *)objectsPassingTest:(BOOL (^)(id obj, BOOL *stop))predicate

NSString *idSearched = ...; 
NSSet *results = [MySet objectsPassingTest:^(id obj,BOOL *stop){ 
    if ([obj valueForKey:@"Unique-Identifier-Key"] == idSearched) return YES; 
    else return NO; 
}]; 

这是最高性能的解决方案吗?据我所知,NSSet使用NSSet的性能比NSArrays更好。而且我不需要一个有序的对象序列。

回答

5

我想你想的实际布局是:

NSDictionary { 
    Unique Value: NSDictionary { 
     "Key2": ValueABC 
     "Key3": ValueDEF 
    } 

    Unique Value: NSDictionary { 
     "Key2": ValueFGH 
     "Key3": ValueJKL 
    } 

    Unique Value: NSDictionary { 
     "Key2": ValueRST 
     "Key3": ValueXYZ 
    } 
} 

基本上,而不是存储的唯一键/值对中的字典,有一个新字典,其中唯一值是到其他数据。如果你的唯一值是NSString那么你会发现你可能会接近O(1)的时间复杂度。

可以用下面的代码的集合转换为上述布局:

NSMutableDictionary *searchable = [NSMutableDictionary dictionary]; 
for (NSDictionary *dict in MySet) 
    [searchable setObject:dict forKey:[dict objectForKey:@"Unique-Identifier-Key"]]; 

(尽管它会更好地直接加载数据到上述,而不是从一组转换它的结构)。然后,每当你想找到你的字典之一:

NSDictionary *dict = [searchable objectForKey:idSearched]; 
+0

谢谢,这听起来很合乎逻辑。如果Unique-Identifier-Key是NSString以外的对象(例如NSManagedObjectID)会怎样?我是否必须将该密钥转换为NSString,还是可以与其他类一起工作(我读过用于密钥的类必须采用NSCopying协议)?以及如何使用自定义键的性能? – FrankZp

+0

@FrankZp:这是正确的,键必须采用'NSCopying',但你已经在字典中使用它,所以不应该有任何问题。使用自定义键时的性能直接关系到'hash'方法的质量。对于大多数Cocoa类型,例如'NSString','hash'方法非常好。绝对最坏的情况是O(n)的复杂性(这与你现在的搜索方式在概念上没有什么不同),但你仍然可以从更简单的代码中获益。 – dreamlax

0

当你使用NSSet这样的效果时,我认为它对性能没有帮助。由于散列算法或某些排序算法,NSSet比NSArray具有更好的性能。如果您使用这样的谓词,我认为NSSet必须搜索整个集合以找到您需要的项目。

我建议你创建一个新的类MyObject的,包含您的NSDictionary,并覆盖hashisEqual

- (BOOL)isEqual:(id)object; 
- (NSUInteger)hash; 

在哈希,你回到你的独特价值的哈希,并且会提高你的表现。但是,如果您有需要搜索很少的对象,你可能只是你简单的谓词去

+0

MyObject会是什么样的类? NSSet的子类? – FrankZp