使用精确子字符串过滤字符串
Posted
技术标签:
【中文标题】使用精确子字符串过滤字符串【英文标题】:Filter string by using exact substring 【发布时间】:2017-02-21 08:27:15 【问题描述】:我需要根据搜索键从 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。
这个谓词怎么写?
【问题讨论】:
是的!因为它也有James
作为子字符串。谓词总是返回那个对象。那么为什么你不需要对象 4。
您可能应该获取所有托管对象并使用 swift filter
方法。它更灵活、更快捷。
@Sweeper:在 fetch 请求中通过 NSPredicate 进行过滤是在 SQlite 级别完成的,其优点是仅将匹配的对象加载到内存中。
【参考方案1】:
您可以使用带有正则表达式模式的谓词 匹配逗号括起来的名称:
let name = "James"
let pattern = "(.*,)?\(NSRegularExpression.escapedPattern(for: name))(,.*)?"
let predicate = NSPredicate(format: "name MATCHES %@", pattern)
(更好的模型是与“名称”实体建立一对多关系,而不是包含逗号分隔名称的单个字符串。)
【讨论】:
我 +1 模型更改。之后搜索/过滤应该会更好、更容易。【参考方案2】:如果我正确理解了您的要求,您是否只想返回那些以 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
这样的条件考虑到名称可以在开头(前面没有逗号)或结尾(后面没有逗号)
【讨论】:
以上是关于使用精确子字符串过滤字符串的主要内容,如果未能解决你的问题,请参考以下文章