【问题标题】:What's the best way to generate this string? (NSMutableString...)生成此字符串的最佳方法是什么? (NSMutableString...)
【发布时间】:2011-06-02 21:29:21
【问题描述】:

我有一个字典,它的键是 NSStrings,它的对象是 NSArray。这是一个例子:

key (NSString) : GroupA 
value (NSArray): John
                 Alex
                 Joe
                 Bob

有很多这样的条目,这只是一个例子。我需要做的是生成这样的字符串(例如:

(GroupA contains[cd] ('John' OR 'Alex' OR 'Joe' OR 'Bob')) AND (GroupB contains[cd] ('Starcraft' OR 'WOW' OR 'Warcraft' OR 'Diablo')) AND ..... 

我将把这个字符串提供给一个 NSPredicate。生成此字符串的最佳方法是什么?我可以使用 for 循环和 if 以及所有这些,但有没有更优雅的方法? 谢谢。

【问题讨论】:

    标签: objective-c cocoa-touch ios nspredicate nsmutablestring


    【解决方案1】:

    这不是一个有效的谓词格式字符串,因此即使最终生成它,也无法将其转换为NSPredicate

    这就是你想要的:

    NSDictionary *groupValuePairs = ....;
    
    NSMutableArray *subpredicates = [NSMutableArray array];
    for (NSString *group in groupValuePairs) {
      NSArray *values = [groupValuePairs objectForKey:group];
      NSPredicate *p = [NSPredicate predicateWithFormat:@"%K IN %@", group, values];
      [subpredicates addObject:p];
    }
    
    NSPredicate *final = [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates];
    

    这没有您原来暗示的不区分大小写和变音符号。如果你真的需要它,那么你需要变得更复杂一些:

    NSDictionary *groupValuePairs = ....;
    
    NSMutableArray *subpredicates = [NSMutableArray array];
    for (NSString *group in groupValuePairs) {
      NSArray *values = [groupValuePairs objectForKey:group];
      NSMutableArray *groupSubpredicates = [NSMutableArray array];
      for (NSString *value in values) {
          NSPredicate *p = [NSPredicate predicateWithFormat:@"%K contains[cd] %@", group, value];
          [groupSubpredicates addObject:p];
      }
      NSPredicate *p = [NSCompoundPredicate orPredicateWithSubpredicates:groupSubpredicates];
      [subpredicates addObject:p];
    }
    
    NSPredicate *final = [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates];
    

    【讨论】:

      【解决方案2】:

      应该是这样的

      NSDictionary *myDict = [NSDictionary dictionaryWithObject:[NSArray arrayWithObjects:@"John",@"Alex",@"Joe",@"Bob",nil] forKey:@"GroupA"];
      NSString *myString = @"(";
      
      int j = 0;
      for(NSString *key in [myDict allKeys]) {
          NSString *value = [myDict valueForKey:key];
          myString = [myString stringByAppendingFormat:@"%@ contains[cd] (", key];
          NSArray *myArray = (NSArray *)value;
      
          int idx = 0;
          for(NSString *name in myArray) {
              myString = [myString stringByAppendingFormat:@"'%@'",name];
              if(idx < [myArray count] - 1) {
                  myString = [myString stringByAppendingFormat:@" OR "];
              } 
              idx++;
          }
      
          myString = [myString stringByAppendingString:@")"];
      
          if(j < [myDict count] -1) {
              myString = [myString stringByAppendingString:@" AND "];
          }
      
          j++;
      
      };
      
      myString = [myString stringByAppendingString:@")"];
      
      NSLog(@"mystring %@",myString);
      

      【讨论】:

      • 如果name 包含撇号怎么办,例如奥哈拉?
      • 真的吗?那么,为什么不提供您自己的答案就对我的答案投反对票呢? #trollin
      • 这不是一个的方法(虽然它有问题)。我建议使用NSMutableString。这样一来,您将拥有 更少的临时对象(从而降低内存使用量)。
      • @brandontreb 好吧,至少你应该知道NSArray -componentsJoinedByString:的方法。这样,您将获得更多可维护的代码。当您仍然创建和增加自己的迭代索引时,我不太明白使用快速枚举的目的。
      • @stam 好电话。那会更有意义。至于递增计数器,我打算使用块进行迭代,但我想让答案更“简单”。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-11
      • 2011-09-05
      • 1970-01-01
      • 1970-01-01
      • 2012-01-28
      • 2011-10-27
      相关资源
      最近更新 更多