搜索对象的NSArray以匹配任何属性的String

时间:2013-10-10 16:43:26

标签: ios objective-c

我有一个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个对象的类别为“doctor”,而另一个对象的电子邮件地址为“smith@doctorsamerica.com”,则它们都应显示在结果中。

3 个答案:

答案 0 :(得分:14)

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

答案 1 :(得分:0)

向您的班级添加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];
    }
}

答案 2 :(得分:0)

不是单独对每个属性名称进行硬编码,而是可以获取类的属性名称数组: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
}