你可能一直做错了,Swift 字符串比较竟然有这么多坑,教你字符串比较的正确姿势

1,213 阅读4分钟

这里每天分享一个 iOS 的新知识,快来关注我吧

前言

作为一个 iOS 开发者,我们经常会遇到字符串比较的问题。比如,我们需要比较两个字符串是否相等,大家都用什么方法呢?

最简单也是最常用的方法是将两个字符串转换为相同的大小写并使用 == 进行比较。然而,有时候不是那么严谨。

== 存在的问题

不同语言和区域对大小写转换有特定的规则,这使得简单的大小写转换并不可靠。让我们来看一个德语的例子:

let string1 = "Fußball"
let string2 = "FUSSBALL"

// 输出 `false`
print(string1.lowercased() == string2.lowercased())

在德语中,ß 的小写形式并不等同于 ss,这导致比较结果为 false

另外,使用 lowercased() 方法会创建一个新的字符串实例,量大的时候这也可能成为性能瓶颈。

再看一个中文声调的例子,大家都知道拼音是有声调的,声调不同,拼音就不同,但是拼音的声调在字符串比较中是忽略的。

let string1 = "pīnyīn"
let string2 = "pinyin"

// 输出 `false`
print(string1.lowercased() == string2.lowercased())

上边的例子中,pīnyīnpinyin 应该是相等的,尽管它们在拼音中表示不同的音节。

解决方案

其实 Foundation 框架就提供了一些解决方案,可以更细致的字符串比较方法。

compare(_:options:)

在进行非用户界面的字符串比较时,我们可以使用 compare(_:options:) 方法或其重载的版本。这个方法允许我们指定特定的比较选项,例如忽略大小写、忽略重音符号或进行数字比较。

let result = string1.compare(string2, options: [.caseInsensitive, .diacriticInsensitive])
if result == .orderedSame {
    print("字符串是相等的。")
}

这种方法不仅能够处理简单的大小写问题,还能处理更多复杂的情况,例如字符的重音符号。通过指定 .diacriticInsensitive 选项,我们可以忽略字符串中的重音符号,从而进行更准确的比较。

用户界面相关的比较

对于用户界面相关的,也就是用户能够看到的,我们应该使用 compare(_:options:range:locale:)localizedStandardCompare(_) 方法。

localizedStandardCompare(_:)

localizedStandardCompare(_:) 在排序将显示给用户的字符串时非常有用,比如文件名、标题或任何需要自然排序顺序的列表。它会以符合人类预期的方式比较字符串,甚至考虑嵌入字符串中的数字值。

let filenames = ["File10.txt", "file2.txt", "FILE1.txt"]
let sortedFilenames = filenames.sorted(
    by: { $0.localizedStandardCompare($1) == .orderedAscending
    })

// 输出 `["FILE1.txt", "file2.txt", "File10.txt"]`
print(sortedFilenames)

这种方法不仅能处理大小写问题,还能处理数字排序问题。例如,上面的代码会将 File10.txt 排在 file2.txt 之后,因为从人类的角度来看,10 比 2 要大。

性能和效率

在选择字符串比较方法时,性能和效率也是需要考虑的重要因素。简单的大小写转换方法虽然直观,但可能在处理大量数据时成为性能瓶颈。

相反,使用 Foundation 提供的比较方法可以更加高效,特别是在需要考虑区域和语言规则的情况下。

实际应用场景

在实际开发中,我们经常需要进行字符串比较。例如,在用户注册时,确保用户名不区分大小写的唯一;

在文件管理系统中,按照自然排序规则显示文件列表;

在搜索功能中,忽略用户输入的大小写和拼音声调符号进行匹配。

通过为我们的具体情况选择最合适的方法,我们可以确保我们的字符串比较不仅正确,而且高效,并且考虑到不同国家民族用户的文化背景。这种细致的方法可以极大地改善用户体验和应用程序的整体可靠性。

最后

字符串比较虽然看似简单,但在实际应用中却充满了各种边界情况。选择合适的方法不仅能提高代码的正确性和效率,还能为用户提供更好的体验。

如果你是一名经验丰富的 Swift 开发者,想要学习高级技巧,可以持续关注我,让我们一起探索这些高级技巧吧。

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 “iOS新知”,每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!