如何为 NSPredicate 连接两个字符串,即名字和姓氏

Posted

技术标签:

【中文标题】如何为 NSPredicate 连接两个字符串,即名字和姓氏【英文标题】:How to join two strings for NSPredicate, ie firstname and lastname 【发布时间】:2012-12-21 05:42:24 【问题描述】:

我有一个 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 中加入名字和姓氏,所以如果我正在搜索"John Sm",那么John Smith 仍然会作为一个选项出现。

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

编辑: 为了进一步说明,我使用了SearchDisplayController 委托方法:

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

我正在使用predicate,如下所示:

newArray = [personObjectArray filteredArrayUsingPredicate:predicate];

【问题讨论】:

查看此处以提供完整信息developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/… 我已经阅读了,但我仍然不明白该怎么做。 您可以更好地使用字典或数组,以便我们轻松实现它 NSArray* ar = [NSArray arrayWithObjects:@"on call", @"I'm on call", @"lala", @"On call", nil]; NSArray* filt = [ar filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self like[c] 'on call'"]]; NSLog([过滤描述]); //输出“on call”、“on call” 我明白这一点,但我有一个动态的对象数组,我想用我的两个 NSString 对象的属性与 searchText 进行比较。 【参考方案1】:

试试这个,

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 ";,它仍然会显示上面的输出。

【讨论】:

谢谢你的作品很好,除了一个小问题。假设我正在输入带有空格的“john”,在我开始输入姓氏之前不会出现任何结果,有没有办法在搜索栏中仍然显示带有“john”的 John Smith? 这对我来说也很好用。在发布之前,我已经对此进行了测试。我想你错过了NSString *text = @"john "; NSString *searchText = [text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 我确定你在过滤之前没有对搜索文本做第二行。基本上,您需要在进行过滤时删除任何前导或尾随空格,否则它将失败。所以如果你不使用第二行,它会失败。 啊,是的,它工作正常,我将我的名字和姓氏字符串初始化为错误的字符串。对不起!但是谢谢你,你帮了我很大的忙,我花了很长时间努力做到这一点! 这不起作用。例如,如果用户键入 John Smith blah blah,它将显示 John Smith。这在代码中很清楚,因为一旦字符串组件超过 1([数组计数] > 1),您仍然只使用数组 [0] 和数组 [1]。最好的解决方法是在你的对象中实现一个方法全名(或者一个类别,如果它是一个 nsmanagedobject),然后使用 predicateWithBlock。【参考方案2】:

上面建议的解决方案不适用于包含两个以上单词的搜索字符串。这是 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)

【讨论】:

我迟到了几年,但是。您的答案是唯一通用的答案 似乎是最好的答案!【参考方案3】:

您可以将字段连接成两个公共字段(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];

【讨论】:

以上是关于如何为 NSPredicate 连接两个字符串,即名字和姓氏的主要内容,如果未能解决你的问题,请参考以下文章

如何为 CoreData 多对多关系编写 NSPredicate

如何为可以返回 nil 的 NSPredicate 创建惰性 var

如何为 CoreData 中包含 NSArray 的二进制数据创建 NSPredicate?

如何为生产模式c# wpf创建连接字符串[重复]

如何为WebJob项目设置连接字符串?

如何为我的数据库连接表