Case insensitive string comparison in Swift
String comparison is a fundamental aspect of many programming tasks, from sorting and searching to data validation. The simplest method to compare two strings ignoring case we might think of is converting them to a common case and using ==
. However, this approach has significant limitations.
Languages and locales have specific rules for case mappings, making simple case conversion unreliable. Let's look at an example in German.
let string1 = "Fußball"
let string2 = "FUSSBALL"
// Prints `false`
print(string1.lowercased() == string2.lowercased())
The lowercase of ß
in German is not equivalent to ss
, leading to a false negative in comparison.
Also note that using lowercased()
creates new string instances, which can be a performance bottleneck. And simple case conversion does not respect locale-specific sorting rules, leading to lists that might appear incorrectly ordered to users.
Fortunately, the Foundation framework offers more nuanced methods for string comparison.
For non-user-facing comparisons we can use the compare(_:options:) method or any of its overloads. It allows us to request specific comparison behaviors like case-insensitive, diacritic-insensitive, or numeric comparison.
let result = string1.compare(string2, options: [.caseInsensitive, .diacriticInsensitive])
if result == .orderedSame {
print("The strings are considered equal.")
}
For user-facing, locale-aware comparison, we should use compare(_:options:range:locale:) or localizedStandardCompare(_:).
localizedStandardCompare(_:)
can come in handy when sorting strings that will be displayed to users, like filenames, titles, or any list that requires natural sorting order. It will compare strings in a way that aligns with human expectations, even considering numeric values embedded in strings.
let filenames = ["File10.txt", "file2.txt", "FILE1.txt"]
let sortedFilenames = filenames.sorted(
by: { $0.localizedStandardCompare($1) == .orderedAscending }
)
// Prints `["FILE1.txt", "file2.txt", "File10.txt"]`
print(sortedFilenames)
By selecting the most suitable method for our specific situation, we can ensure that our string comparisons are not only correct but also efficient and considerate of the user's cultural context. This careful approach can greatly improve the user experience and the overall reliability of our applications.
If you're an experienced Swift developer looking to learn advanced techniques, check out my latest book Swift Gems. It’s packed with tips and tricks focused solely on the Swift language and Swift Standard Library. From optimizing collections and handling strings to mastering asynchronous programming and debugging, "Swift Gems" provides practical advice that will elevate your Swift development skills to the next level. Grab your copy and let's explore these advanced techniques together.