【问题标题】:How to search an NSSet or NSArray for an object which has an specific value for an specific property?如何在 NSSet 或 NSArray 中搜索具有特定属性的特定值的对象?
【发布时间】:2011-03-05 19:47:21
【问题描述】:

如何在 NSSet 或 NSArray 中搜索具有特定属性的特定值的对象?

示例:我有一个包含 20 个对象的 NSSet,每个对象都有一个 type 属性。我想得到第一个有[theObject.type isEqualToString:@"standard"]的对象。

我记得有可能以某种方式对这类东西使用谓词,对吧?

【问题讨论】:

    标签: iphone objective-c nsarray nspredicate nsset


    【解决方案1】:
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"type == %@", @"standard"];
    NSArray *filteredArray = [myArray filteredArrayUsingPredicate:predicate];
    id firstFoundObject = nil;
    firstFoundObject =  filteredArray.count > 0 ? filteredArray.firstObject : nil;
    

    注意:在 NSSet 中 first 找到对象的概念没有意义,因为集合中对象的顺序是未定义的。

    【讨论】:

    • 如果对象没有'type'属性,但有另一个对象(比如说'job'),它是否工作,这是具有'type'属性的'job'?
    • 是的,但是对于要在谓词中使用的键,类必须是键值编码兼容的。
    • indexOfObjectPassingTest 似乎更好有两个原因:(1)您使用实际方法而不是 string (2)您在找到的“第一个”元素上停止 -没有订购一套并不重要,您可能仍然只想要一件。
    【解决方案2】:

    您可以像 Jason 和 Ole 所描述的那样获得过滤后的数组,但由于您只想要一个对象,我会使用 - indexOfObjectPassingTest:(如果它在一个数组中)或 -objectPassingTest:(如果它在一个集合中)和避免创建第二个数组。

    【讨论】:

    • 这对于 NSArray 来说似乎是个好主意,但 NSSet 中的方法实际上是 -objectsPassingTest: (注意复数),所以如果我理解正确的话,这个想法在那里不可能直接实现。
    【解决方案3】:

    一般来说,我使用indexOfObjectPassingTest:,因为我发现用Objective-C 代码而不是NSPredicate 语法来表达我的测试更方便。这是一个简单的例子(假设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)
    

    【讨论】:

      【解决方案4】:
      NSArray* results = [theFullArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF.type LIKE[cd] %@", @"standard"]];
      

      【讨论】:

        猜你喜欢
        • 2018-08-03
        • 2014-05-03
        • 2021-12-12
        • 1970-01-01
        • 1970-01-01
        • 2017-02-27
        • 2021-05-26
        相关资源
        最近更新 更多