【问题标题】:Search NSArray of objects for String matching any property在对象的 NSArray 中搜索与任何属性匹配的字符串
【发布时间】:2013-10-10 16:43:25
【问题描述】:

我有一个 NSArray 对象,这些对象有 10 个属性。我想对这些对象进行文本搜索。

我知道如何一次搜索 1 个属性,但是有没有一种简单的方法可以一次搜索所有属性?

以下是我的对象具有的属性列表:

@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * phone;
@property (nonatomic, retain) NSString * secondaryPhone;
@property (nonatomic, retain) NSString * address;
@property (nonatomic, retain) NSString * email;
@property (nonatomic, retain) NSString * url;
@property (nonatomic, retain) NSString * category;
@property (nonatomic, retain) NSString * specialty;
@property (nonatomic, retain) NSString * notes;
@property (nonatomic, retain) NSString * guid;

如果我搜索“医生”,我想查看其中 1 个或多个这些属性中包含“医生”一词的所有结果。例如,如果 1 个对象的类别为“医生”,而另一个对象的电子邮件地址为“smith@doctorsamerica.com”,则它们都应显示在结果中。

【问题讨论】:

    标签: ios objective-c


    【解决方案1】:
     NSString *searchTerm = @"search this";
     NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF LIKE[cd] %@", searchTerm];
     NSArray *filtered = [array filteredArrayUsingPredicate:predicate];
    

    如果有特定属性,您可以将谓词更改为:

     NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.propertyName LIKE[cd] %@", searchTerm];
    

    要搜索所有属性,您必须使用逻辑运算符将它们绑定在一起

      NSString *query = @"blah";
      NSPredicate *predicateName = [NSPredicate predicateWithFormat:@"name contains[cd] %@", query];
      NSPredicate *predicatePhone = [NSPredicate predicateWithFormat:@"phone contains[cd] %@", query];
      NSPredicate *predicateSecondaryPhone = [NSPredicate predicateWithFormat:@"secondaryPhone contains[cd] %@", query];
      NSArray *subPredicates = [NSArray arrayWithObjects:predicateName, predicatePhone, predicateSecondaryPhone, nil];
    
      NSCompoundPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates];
    

    【讨论】:

      【解决方案2】:

      在你的类中添加一个matches: 方法:

      - (BOOL)matches:(NSString *)term {
          if ([self.name rangeOfString:term options:NSCaseInsensitiveSearch| NSDiacriticInsensitiveSearch].location != NSNotFound) {
              return YES;
          } else if ([self.phone rangeOfString:term options:NSCaseInsensitiveSearch| NSDiacriticInsensitiveSearch].location != NSNotFound) {
              return YES;
          } else if (...) { // repeat for all of the properties
              return YES;
          }
      
          return NO;
      }
      

      现在您可以遍历您的对象来检查每个对象:

      NSArray *peopleArray = ... // the array of objects
      NSString *someTerm = ... // the search term
      NSMutableArray *matches = [NSMutableArray array];
      for (id person in peopleArray) {
          if ([person matches:someTerm]) {
              [matches addObject:person];
          }
      }
      

      【讨论】:

        【解决方案3】:

        您可以获取类的属性名称数组,而不是单独对每个属性名称进行硬编码:List of class properties in Objective-C,(假设它们都是字符串,或者您可以检查每个属性的类型是否属于类 NSString 但我'我不知道该怎么做)

        然后在您想要搜索的每个对象上,您可以遍历每个对象的属性并检查每个对象的值:

        id objectValue = [object valueForKey:[NSString stringWithUTF8String:propertyName]];
        // let's say the property is a string
        NSString *objectValueString = (NSString *)objectValue; 
        

        然后您可以检查该属性是否与您的 searchTerm 匹配,例如:

        BOOL propertyValueMatchesSearchTerm = [objectValueString rangeOfString:mySearchTermString].location != NSNotFound; 
        
        if (propertyValueMatchesSearchTerm) {
           // add object to search results array
        }
        

        【讨论】:

          猜你喜欢
          • 2014-09-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-03-18
          • 1970-01-01
          • 2018-05-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多