-3

の基準に一致tagsする内部NSDictionaryを見つけようとしていますが、それらの正確な配列を多かれ少なかれ含む結果が必要です。この例では、 の 2 番目だけが必要です。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ます。あなたの例では、2番目の辞書のみを含む配列を返します。

更新:「タグ」値が指定された要素を持つ配列であるが、順序とは無関係であるすべての辞書を見つけるには、次の少し複雑な述語が機能する必要があります。

[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 に答える