用字符串中的基本字符替换重音字符 - ± -> a , ć -> c

Replace Accent character with basic in a String - ą -> a , ć -> c

我在搜索数据库时从波兰语字母表中删除了重音字符。这样用户就可以输入没有重音的文本。

我在我的 TableView 搜索控制器中使用它,它有大约 15,000 个字符串。代码有效,但速度非常慢,应用程序会在输入每个字母时冻结一秒钟。

有没有人有更有效的解决方案?

我的 TableView 过滤器:

//My old method which didn't convert accent letters and works smoothly
var arr = dataSetArray.filter({[=10=].lowercased().contains(searchText.lowercased())})

//My new filtering method
var arr = dataSetArray.filter({[=10=].forSorting().contains(searchText.lowercased())})

我的分机:

extension String {
func forSorting() -> String {
    let set = [("ą", "a"), ("ć", "c"), ("ę", "e"), ("ł", "l"), ("ń", "n"), ("ó", "o"), ("ś", "s"), ("ź", "z"), ("ż", "z")]
    let ab = self.lowercased()
    let new = ab.folding(options: .diacriticInsensitive, locale: nil)
    let final = new.replaceCharacters(characters: set)
    return final
    }
}

extension String {
    func replaceCharacters(characters: [(String, String)]) -> String
    {
        var input: String = self
        let count = characters.count
        if count >= 1
        {
            for i in 1...count
            {
                let c = i - 1
                let first = input
                let working = first.replacingOccurrences(of: characters[c].0, with: characters[c].1)
                input = working
            }
        }
        return input
    }
}

使用 caseInsensitivediacriticInsensitive 选项尝试 range(of

let arr = dataSetArray.filter{ [=10=].localizedStandardRange(of: searchText) != nil }

没有扩展名

您可以使用 localizedStandardContains,其中 returns 一个布尔值,指示字符串是否包含给定的字符串,同时考虑到当前的语言环境。

声明

func localizedStandardContains<T>(_ string: T) -> Bool where T : StringProtocol

Discussion This is the most appropriate method for doing user-level string searches, similar to how searches are done generally in the system. The search is locale-aware, case and diacritic insensitive. The exact list of search options applied may change over time

extension Collection where Element: StringProtocol {
    public func localizedStandardFilter(_ element: Element) -> [Element] {
        filter { [=11=].localizedStandardContains(element) }
    }
}

let array = ["cafe","Café Quente","CAFÉ","Coffe"]
let filtered = array.localizedStandardFilter("cafe")

filtered  // ["cafe", "Café Quente", "CAFÉ"]