web-dev-qa-db-ja.com

特定のプロパティに特定の値を持つオブジェクトのNSSetまたはNSArrayを検索する方法は?

特定のプロパティに特定の値を持つオブジェクトのNSSetまたはNSArrayを検索する方法は?

例:20個のオブジェクトを持つNSSetがあり、すべてのオブジェクトにtypeプロパティがあります。 [theObject.type isEqualToString:@"standard"]を持つ最初のオブジェクトを取得したい。

この種のものに何らかの形で述語を使用することが可能であったことを覚えていますか?

51
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"type == %@", @"standard"];
NSArray *filteredArray = [myArray filteredArrayUsingPredicate:predicate];
id firstFoundObject = nil;
firstFoundObject =  filteredArray.count > 0 ? filteredArray.firstObject : nil;

NB:NSSet内で見つかったfirstという概念は、セット内のオブジェクトの順序が定義されていないため、意味がありません。

78
Ole Begemann

JasonとOleが説明したようにフィルター処理された配列を取得できますが、1つのオブジェクトだけが必要なので、- indexOfObjectPassingTest:(配列内にある場合)または-objectPassingTest:(セット内にある場合)を使用します2番目の配列を作成しないでください。

17
NSResponder

一般的に、indexOfObjectPassingTest:テストをNSPredicate構文ではなくObjective-Cコードで表現する方が便利だと感じたため。以下に簡単な例を示します(integerValueは実際にはプロパティであったと想像してください):

NSArray *array = @[@0,@1,@2,@3];
NSUInteger indexOfTwo = [array indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
    return ([(NSNumber *)obj integerValue] == 2);
}];
NSUInteger indexOfFour = [array indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
    return ([(NSNumber *)obj integerValue] == 4);
}];
BOOL hasTwo = (indexOfTwo != NSNotFound);
BOOL hasFour = (indexOfFour != NSNotFound);
NSLog(@"hasTwo: %@ (index was %d)", hasTwo ? @"YES" : @"NO", indexOfTwo);
NSLog(@"hasFour: %@ (index was %d)", hasFour ? @"YES" : @"NO", indexOfFour);

このコードの出力は次のとおりです。

hasTwo: YES (index was 2)
hasFour: NO (index was 2147483647)
15
Carl Veazey
NSArray* results = [theFullArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF.type LIKE[cd] %@", @"standard"]];
4
Jason Coco