2017-02-21 122 views
0

我需要根据搜索关键字从CoreData中搜索和获取对象。 我的核心数据对象包含一个名为names的字符串属性。我的要求如下:使用确切的子字符串筛选字符串

managedObject1.names = "James,James Willson,Willson James,James Camaroon" 
managedObject2.names = "James Willson,James,Willson James,James Camaroon" 
managedObject3.names = "James Camaroon,James Willson,Willson James,James" 
managedObject4.names = "James Willson,Willson James,James Camaroon" 

当用户使用'James'搜索关键字时,我只需要managedObject1,managedObject2和managedObject3。我试过NSPredicate(format: "names contains[d] %@", name),但它也返回了managedObject4。

如何为此编写谓词?

+0

是啊!因为它也有'詹姆斯'作为子串。谓词总是返回该对象。那么为什么你不需要对象4. –

+0

你应该可能得到所有的托管对象,并使用快捷的'filter'方法。它更灵活,速度更快。 – Sweeper

+1

@Sweeper:在获取请求中通过NSPredicate进行筛选是在SQlite级别完成的,并且具有只将匹配对象加载到内存中的优势。 –

回答

2

您可以使用谓词与 匹配用逗号包围的名正则表达式模式:

let name = "James" 
let pattern = "(.*,)?\(NSRegularExpression.escapedPattern(for: name))(,.*)?" 
let predicate = NSPredicate(format: "name MATCHES %@", pattern) 

(更好的模式将有一个“名称”实体一对多的关系,而不是包含逗号分隔名称的单个字符串。)

+0

我+1模型的变化。之后搜索/过滤应该会更好,更容易。 – Larme

0

因此,如果我正确理解您的要求,那么您只想返回那些没有任何名字或姓氏的名称为James的对象?

在这种情况下,你可以有这样的

let names = "James Willson,Willson James,James Camaroon" 
let searchedString = "James" 
let searchedStringCount = searchedString.characters.count 

let endIndex = names.index(names.startIndex, offsetBy: searchedStringCount + 1) 
let startIndex = names.index(names.endIndex, offsetBy: -(searchedStringCount + 1)) 

let startString = names.substring(to: endIndex) // prints "James " 
let endString = names.substring(from: startIndex) // prints "maroon" 

let shouldBeReturned = startString == "\(searchedString)," || endString == ",\(searchedString)" || names.contains(",\(searchedString),") // prints false 

这样的条件的情况考虑到一个事实,即名称可以是在开始(在它的前面没有昏迷)或结尾(后面没有逗号)