-3

我试图找到符合条件的内部,tags并且NSDictionary我希望结果具有那些确切的数组,不多也不少。在这个例子中,我只想要第二个。myArstronlyNSDictionarymyAr

我虽然试图通过使用谓词来实现这一点,但是当我使用数组时它总是返回空。

我正在尝试使用数组进行过滤,但这不起作用。我想知道是否有人可以告诉我我做错了什么以及如何实现我的目标。提前致谢

  NSArray * myAr = @[ @{ @"tags": @[@"one",@"two",@"three"],
                           @"number": @"4"
                          },
                        @{ @"tags": @[@"one",@"two"],
                           @"number":@"4"
                        },
                        @{ @"tags": @[@"one",@"two",@"four"],
                           @"number":@"4"
                        },
                        @{ @"tags": @[@"chacho",@"chocho"],
                           @"number":@"4"
                        },
                        @{ @"tags": @[@"one"],
                           @"number":@"4"
                        } ];

    NSArray* str = @[@"one",@"two"];
    NSPredicate* pre = [NSPredicate predicateWithFormat:@"tags CONTAINS %@ ",str];
    myAr = [myAr filteredArrayUsingPredicate:pre];
    NSLog(@"%@",myAr);
4

3 回答 3

3

如果我正确理解您的问题,您只需将谓词中的“CONTAINS”替换为“=”:

[NSPredicate predicateWithFormat:@"tags = %@ ",str]

这给出了一个包含所有字典的数组,其中“标签”值等于给定的数组str。在您的示例中,它仅返回一个包含第二个字典的数组。

更新:要查找“标签”值是具有给定元素的数组但独立于 order的所有字典,以下稍微复杂的谓词应该起作用:

[NSPredicate predicateWithFormat:@"tags.@count = %d AND SUBQUERY(tags, $t, $t in %@).@count = %d",
     [str count], str, [str count]];

更新2:这太复杂了,以下谓词似乎也有效:

[NSPredicate predicateWithFormat:@"tags.@count = %d AND ALL tags in %@",
    [str count], str]

(我假设str它只包含不同的元素。)

于 2013-08-05T21:35:49.283 回答
1

对于既不使用 for 循环也不使用谓词格式字符串的答案,请尝试使用块并使用 NSSet 来确定要匹配的标记集是否等于数组元素的标记集。例如:

NSSet* desiredTags = [NSSet setWithObjects:@"one", @"two", nil];

NSPredicate *tagFilterPredicate = [NSPredicate
    predicateWithBlock:^BOOL (id data, NSDictionary *bindings) {
        NSSet *tags = [NSSet setWithArray:[data objectForKey:@"tags"]];
        return [desiredTags isEqual:tags];
    }];

NSArray *resultArray = [myArr filteredArrayUsingPredicate:tagFilterPredicate];

请记住,这确实为每次迭代分配了一个集合。所以,如果你想避免分配,这是不够的。否则,它至少避免了格式字符串。

于 2013-08-05T21:53:04.317 回答
0

一种蛮力的方法是删除您的谓词并枚举:

NSArray *required = @[@"one", @"two"];
NSMutableArray *matches = [@[] mutableCopy];
[myAr enumerateObjectsUsingBlock:^(NSDictionary *dict, NSUInteger idx, BOOL *stop) {
  [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
    if ([obj isKindOfClass:[NSArray class]]) {
      BOOL match = YES;
      for (NSString *item in required) {
        if (![obj containsObject:item]) {
          match = NO;
          break;
        }
      }
      if (match && [(NSArray *)obj count] == required.count) {
        [matches addObject:obj];
      }
    }
  }];
}];
于 2013-08-05T21:28:00.707 回答