1

给定的是一个带有对象的 NSArray,每个对象都有一个带有浮点数的 NSArray,存储为 NSNumber。

我正在尝试创建一个 NSPredicate 来根据浮点值过滤我的主数组。那么,例如,如何获取所有值为 234.6 +/- 0.8 的对象作为子数组中的浮点数之一?

我可以为浮点数的一维 NSArray 做这样的事情:

float targetFloat = 234.6;
float delta = 0.8;

filterPredicate = [NSPredicate predicateWithFormat: @"myFloat > %f AND myFloat < %f", (targetFloat - delta),  (targetFloat + delta)];
filteredArray = [originalArray filteredArrayUsingPredicate: filterPredicate];

但是如何使用 NSNumbers 为我的 2D NSArray 更改它?

4

2 回答 2

4

您可以在谓词中使用“SELF[index]”来访问子数组的特定元素。以下谓词查找第一个元素在指定范围内的所有子数组:

float lowValue = 1.5;
float hiValue = 2.5;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF[0] > %f AND SELF[0] < %f", lowValue, hiValue];
NSArray *filtered = [array filteredArrayUsingPredicate:predicate];

如果要查找包含指定范围内任意数字的子数组,请使用

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY SELF BETWEEN %@", @[@(lowValue), @(hiValue)]];
于 2013-04-12T19:25:31.820 回答
1

您的谓词可以访问对象的属性,该属性按名称保存数组;我list在下面的示例中调用了它。然后使用ANY关键字检查数组中的所有值,并BETWEEN确定这些值是否在您选择的范围内。

#import <Foundation/Foundation.h>

@interface Grumolo : NSObject
@property (copy, nonatomic) NSArray * list;
@end

@implementation Grumolo
- (NSString *)description
{
    return [NSString stringWithFormat:@"%@: %p, list: %@", NSStringFromClass([self class]), self, [self list]];
}
@end

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        float target = 234;
        float delta = 0.8;
        NSPredicate * p = [NSPredicate predicateWithFormat:@"ANY list BETWEEN %@", @[@(target-delta), @(target+delta)]];

        NSArray * yes = @[@234, @10, @100];
        NSArray * yes2 = @[@0, @16, @234];
        NSArray * no = @[@1, @2, @3];

        Grumolo * g1 = [Grumolo new];
        [g1 setList:yes];
        Grumolo * g2  = [Grumolo new];
        [g2 setList:yes2];
        Grumolo * g3 = [Grumolo new];
        [g3 setList:no];


        NSLog(@"%@", [@[g1, g2, g3] filteredArrayUsingPredicate:p]);


    }
    return 0;
}

您可能还想尝试predicateWithBlock:,它可以让您表达您正在尝试对每个数组进行传统循环执行的操作,YES如果您找到符合您的标准的元素并且NO如果您用尽列表,则返回。

NSPredicate * pb = [NSPredicate predicateWithBlock:^BOOL(Grumolo * evaluatedObject, NSDictionary *bindings) {
        NSArray * list = [evaluatedObject list];
        __block BOOL result = NO;
        [list enumerateObjectsUsingBlock:^(NSNumber * obj, NSUInteger idx, BOOL *stop) {
            BOOL moreThanLower = (NSOrderedDescending == [obj compare:@(target-delta)]);
            BOOL lessThanUpper = (NSOrderedAscending == [obj compare:@(target+delta)]);
            if( moreThanLower && lessThanUpper ){
                *stop = YES;
                result = YES;
                return;
            }
        }];

        return result;
    }];
于 2013-04-12T19:46:24.257 回答