【问题标题】:NSPredicate of multidimensional NSArray多维 NSArray 的 NSPredicate
【发布时间】:2013-04-12 19:11:06
【问题描述】:

Given 是一个带有对象的 NSArray,每个对象都有一个带有浮点数的 NSArray,存储为 NSNumbers。

我正在尝试创建一个 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 更改它?

【问题讨论】:

    标签: objective-c nsarray nspredicate nsnumber


    【解决方案1】:

    您可以在谓词中使用“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)]];
    

    【讨论】:

      【解决方案2】:

      您的谓词可以通过名称访问保存数组的对象的属性;在下面的示例中,我将其称为 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:,它可以让您表达您想要对每个数组进行传统循环执行的操作,如果您找到符合您条件的元素,则返回YESNO如果你用完了列表。

      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;
          }];
      

      【讨论】:

      • “ANY list BETWEEN”是让它工作的关键。谢谢,
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多