【问题标题】:How to search for string if it contains whitespace in Swift?如果在 Swift 中包含空格,如何搜索字符串?
【发布时间】:2021-09-05 05:57:13
【问题描述】:

目前,在搜索中,我正在寻找一个包含一些字符的字符串:

func search(for keyword: String?) {
    self.keyword = keyword
    guard let keyword = keyword?
        .folding(options: .diacriticInsensitive, locale: nil)
        .lowercased(),
        !keyword.isEmpty else {
        filteredNames = names
        return
    }
    filteredNames = names
        .filter { $0.title.lowercased()
            .folding(options: .diacriticInsensitive, locale: nil)
            .contains(keyword)
        }
}

问题是当列表更大时,它显示的内容超出预期。 我不会使用 .contain(keyword),而是 .starts(with: keyword),但它会错过一些结果。

假设我有一个数组: let myArray = ["name", "my name", "some name", "else string", "string", "stringname"] 因此,在查找“ame”时,它不会显示包含字符串的所有内容,而我想要的是仅在数组中的单词以该字符串开头时才显示。因此,当输入“名称”时,它应该返回“名称”、“某个名称”,但 NOT “字符串名称”

【问题讨论】:

    标签: ios arrays swift sorting


    【解决方案1】:

    另一种方法是使用正则表达式和range(of:options:)进行搜索

    好处是没有创建额外的对象,它是 O(n) 并且您可以同时指定不区分大小写和不区分变音符号的选项。正则表达式模式中的\b 表示单词边界

    let keyword = "name"
    let myArray = ["name", "my name", "some name", "else string", "string", "stringname"]
    
    let filtered = myArray.filter {
        $0.range(of: "\\b\(keyword)", options: [.regularExpression, .caseInsensitive, .diacriticInsensitive]) != nil
    }
    print(filtered)
    

    【讨论】:

    • 这是我要发布的答案,但最后没有 \b,因为我相信 OP 想要以搜索字符串开头的单词,例如“nameless”
    • @JoakimDanielson 对,感谢您指出。
    【解决方案2】:

    你可以这样做 -

    extension String {
        // Assumption: Both `keyword` & `self` are already lowercased
        func hasMatch(for keyword: String) -> Bool {
            let comps = self
                .folding(options: .diacriticInsensitive, locale: nil)
                .components(separatedBy: " ")
            return (comps.first(where: { $0.starts(with: keyword) }) != nil)
        }
    }
    

    现在您的过滤器逻辑可以像这样使用它 -

    filteredNames = names
        .filter { $0.title.lowercased()
            .hasMatch(for: keyword)
        }
    

    【讨论】:

      【解决方案3】:

      您可以将每个 String 按空格分开并匹配每个组件。

      let searchTerm = "name"
      let myArray = ["name", "my name", "some name", "else string", "string", "stringname"]
      
      let matches = myArray.filter {
        $0.components(separatedBy: " ").contains {
          $0.hasPrefix(searchTerm)
        }
      }
      

      留给读者的改进:

      • 用任何类型的空格分割字符串
      • 不区分大小写、不区分变音符号的搜索

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-13
        • 1970-01-01
        • 2011-03-11
        • 1970-01-01
        • 2016-04-30
        相关资源
        最近更新 更多