ios - 在给定几个条件的情况下,如何有效地搜索字符串数组中的字符串?
问题描述
我正在尝试过滤字符串数组并根据两个用例返回匹配的字符串。
情况 1:仅当 searchString 位于单词的开头时才匹配。
例如,如果我们有一个数组 -> ["Ralph Breaks The Internet", "Bohemian Rhapsody", "Spider-Man: Into the Spider-Verse"] 并且我们试图将它与搜索字符串 "r" 匹配
在这种情况下,我们应该返回 ["Ralph Breaks The Internet", "Bohemian Rhapsody"],因为 "r" 在开头,如 ralph 中的 r 和 rhapsody 中的 r。但是“蜘蛛侠:平行宇宙”不匹配,因为 r 在中间。
情况 2:如果 searchText 的顺序不准确,也匹配。
例如,如果我们有一个数组 -> ["Ralph Breaks The Internet", "Bohemian Rhapsody", "Spider-Man: Into the Spider-Verse"] 并且我们试图将它与搜索字符串 "Rhapsody Bohemian" 匹配,即使顺序不同,它也应该仍然匹配。
这是我到目前为止所尝试的:
func searchMovies(_ movieNames: [String], with searchText: String) -> [String] {
var matchedMovies = [String]()
for movie in movieNames {
let movieWords = movie.split(separator: " ")
let searchTextWords = searchText.split(separator: " ")
var count = searchTextWords.count
loop:
for word in movieWords {
for text in searchTextWords {
let pattern = "\\b\(text)"
if let _ = word.range(of: pattern, options: [.regularExpression, .caseInsensitive]) {
count -= 1
}
if count == 0 {
matchedMovies.append(movie)
break loop
}
}
}
}
return matchedMovies
}
我知道这不是一种有效的方法。如果有人可以指导我朝某个方向前进,这样我就可以更有效地解决同样的事情,那就太好了。
解决方案
对于您的具体情况,您可以像这样格式化您的正则表达式模式:
"^(?=.*\\bRhapsody)(?=.*\\bBohemian).*$"
为了使它灵活,你可以这样写你的函数:
func searchMovies(_ movieNames: [String], with searchText: String) -> [String] {
// split search text into "words"
let words: [String] = searchText.components(separatedBy: " ")
// start of pattern string
var pattern: String = "^"
// for each word in search text
words.forEach { w in
// append regex to search for words beginning with word
pattern += "(?=.*\\b\(w))"
}
// end of pattern string
pattern += ".*$"
return movieNames.filter { (movie) -> Bool in
if let _ = movie.range(of: pattern, options: [.regularExpression, .caseInsensitive]) {
return true
}
return false
}
}
您可以使用以下命令调用它:
let a: [String] = [
"Ralph Breaks The Internet",
"Bohemian Rhapsody",
"Spider-Man: Into the Spider-Verse"
]
let matchingArray = searchMovies(a, with: "Rhapsody Bohemian")
请注意,这将匹配单词的开头(如您使用“r”所示),因此这将返回相同的结果:
let matchingArray = searchMovies(a, with: "Rhap Boh")
推荐阅读
- c# - EF Core - 从集合导航属性中删除相关实体不会更新数据库
- vagrant - 与 Mac 相比,PC 上的 Vagrant + PHPUnit 性能太慢
- javascript - 当我认为它应该是 json 时,获取返回一个承诺?然后它没有正确更新redux
- javascript - 无法在 VueJS 中滚动自定义滚动条
- c# - 尝试激活时无法解析类型“System.Int32”的服务
- javascript - 在一个文档中单独观看时间
- java - java中的运算符“new”,创建字符串
- php - Laravel 5 登录功能更改参数
- python - 找到两个 pytorch 张量的不相交
- r - r 中的条形图,每个 x 变量有多个条形图