我有一个Person
对象,它有两个NSString
属性; firstName and lastName
。
我目前正在使用NSPredicate
,所以:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(firstName contains[cd] %@) OR (lastName contains[cd] %@)", searchText, searchText];
因此,例如,假设我正在搜索名称"John Smith"
。在我的搜索栏中,如果我输入"Joh"
,则John Smith
将作为选项显示。这很好,但如果我输入"John Sm"
,它将变为空白。
如何在predicate
中加入firstName和lastName,以便在我搜索"John Sm"
时,John Smith
仍会显示为选项。
我希望这是有道理的。感谢。
编辑:
为了进一步澄清,我正在使用SearchDisplayController
委托方法:
-(void)filterContentForSearchText:(NSString *)searchText scope:(NSString *)scope;
我正在使用predicate
,所以:
newArray = [personObjectArray filteredArrayUsingPredicate:predicate];
答案 0 :(得分:19)
试试这个,
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 = @"Smi Joh";
或text = @"John ";
或text = @" smi";
或text = @"joh smi ";
,它仍会显示上述输出。
答案 1 :(得分:1)
您可以将字段连接到两个公共字段(第一个LastName和最后一个FirstName)
- (NSString *)firstLastName {
return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
}
- (NSString *)lastFirstName {
return [NSString stringWithFormat:@"%@ %@", self.lastName, self.firstName];
}
然后使用'过滤此字段,包含[cd]'
[NSPredicate predicateWithFormat:@"(firstLastName contains[cd] %@) OR (lastFirstName contains[cd] %@)" , self.searchBar.text, self.searchBar.text];
答案 2 :(得分:1)
上面建议的解决方案不适用于具有两个以上单词的搜索字符串。这是swift中更全面的实现。此解决方案还允许在记录中添加更多字段,如果您的目标是实现跨名称,电子邮件,电话号码等的全文搜索。在这种情况下,只需将NSPredicate更新为OR newField CONTAINS[cd] %@
并确保添加字符串替换列表中的额外$ 0。
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)