14

我有一个Person具有两个NSString属性的对象;firstName and lastName. 我目前正在使用NSPredicate这样的:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(firstName contains[cd] %@) OR (lastName contains[cd] %@)", searchText, searchText];

因此,例如,假设我正在搜索 name "John Smith"。如果我在我的搜索栏中输入"Joh",那么John Smith将作为一个选项出现。这很好,但如果我输入"John Sm"它会变成空白。

我如何加入 firstName 和 lastName ,predicate所以如果我正在搜索"John Sm"thenJohn Smith仍然会作为一个选项出现。

我希望这是有道理的。谢谢。

编辑:为了增加一点说明,我使用了SearchDisplayController委托方法:

-(void)filterContentForSearchText:(NSString *)searchText scope:(NSString *)scope;

我正在使用predicate这样的:

newArray = [personObjectArray filteredArrayUsingPredicate:predicate];
4

3 回答 3

20

试试这个,

NSString *text = @"John Smi";
NSString *searchText = [text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

NSArray *array = [searchText componentsSeparatedByString:@" "];
NSString *firstName = searchText;
NSString *lastName = searchText;
NSPredicate *predicate = nil;

if ([array count] > 1) {
    firstName = array[0];
    lastName = array[1];
    predicate = [NSPredicate predicateWithFormat:@"(firstName CONTAINS[cd] %@ AND lastName CONTAINS[cd] %@) OR (firstName CONTAINS[cd] %@ AND lastName CONTAINS[cd] %@)", firstName, lastName, lastName, firstName];
} else {
    predicate = [NSPredicate predicateWithFormat:@"firstName CONTAINS[cd] %@ OR lastName CONTAINS[cd] %@", firstName, lastName];
}

NSArray *filteredArray = [people filteredArrayUsingPredicate:predicate];
NSLog(@"%@", filteredArray);

输出:

(
        {
        firstName = John;
        lastName = Smith;
    }
)

这里的 text 代表搜索到的文本。上面的好处是,即使你通过text = @"Smi Joh";ortext = @"John ";text = @" smi";or text = @"joh smi ";,它仍然会显示上面的输出。

于 2012-12-21T06:31:03.310 回答
3

上面建议的解决方案不适用于包含两个以上单词的搜索字符串。这是 swift 中更彻底的实现。如果您的目标是跨姓名、电子邮件、电话号码等实现全文搜索,此解决方案还允许在记录上添加更多字段。在这种情况下,只需将 NSPredicate 更新为OR newField CONTAINS[cd] %@并确保在字符串替换列表。

let searchText = search.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
let words = searchText.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
let predicates = words.map { NSPredicate(format: "firstName CONTAINS[cd] %@ OR lastName CONTAINS[cd] %@", $0,$0) }

let request = NSFetchRequest()
request.predicate = NSCompoundPredicate(type: NSCompoundPredicateType.AndPredicateType, subpredicates: predicates)
于 2015-05-29T15:48:28.973 回答
1

您可以将字段连接成两个公共字段(firstLastName 和 lastFirstName)

- (NSString *)firstLastName {
      return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
}

- (NSString *)lastFirstName {
      return [NSString stringWithFormat:@"%@ %@", self.lastName, self.firstName];
}

然后使用 'contains[cd]' 过滤此字段

[NSPredicate predicateWithFormat:@"(firstLastName contains[cd] %@) OR (lastFirstName contains[cd] %@)" , self.searchBar.text, self.searchBar.text];
于 2015-03-03T17:14:47.003 回答