如何为NSPredicate连接两个字符串,即firstname和lastname

时间:2012-12-21 05:42:24

标签: iphone objective-c ios nsstring nspredicate

我有一个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];

3 个答案:

答案 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)