4 ms·
IMO, Swift is a language that gets it right, by exposing an interface which feels to very closely match how "humans" understand text — the default String interf
by _rend 5y ago
IMO, Swift is a language that gets it right, by exposing an interface which feels to very closely match how "humans" understand text — the default String interface is a collection of grapheme clusters, while `.utf8View`, `.utf16View`, and `.unicodeScalarView` are optional views which expose data explicitly encoded as needed.
Swift is pretty pedantically strict about Unicode correctness, and avoids some pitfalls which lead to incorrect handling (e.g., integer-based indexing). This means that the traditional way many developers might be used to interacting with strings is cumbersome and annoying — but once you get past the initial hurdle*, most operations are actually (1) really easy, especially when expressed in terms of generic Sequence/Collection operations, and (2) much more difficult to get wrong.
*I think the largest part of that hurdle is overcoming what you may have gotten used to from other languages, i.e., treating strings as an array of "characters", for some language/library definition of "character" (whether bytes, code points, etc.). It's relatively rare that you actually care about indexing into an arbitrary spot in a string: instead, combinations of slicing operations (including `prefix(_:)`, `dropFirst(_:)`, `take(while:)`, etc.) and generic Collection operations will get you what you want. Things like `.reversed()`, `.sorted(), and `.shuffled()` all work trivially correctly too (since you're not operating on a bag of bytes), and it's exceedingly rare that user input will confound the operations you might need to perform. (Exception: operations like case folding and collection, which are locale-specific, need special handling through a framework like Foundation.)
To be clear: not everything is sunshine and roses, but an amazing amount of functionality "falls out" of basic protocol conformances on String, and its exposure as a Collection of grapheme clusters.
Given a specific string manipulation task, I'd be happy to provide an example of what it might look like in Swift!
- rudedogg 5y ago> Given a specific string manipulation task, I'd be happy to provide an example of what it might look like in Swift! How would you safely get the nth index of a string, clamped to the valid indexes? So if the nth index is out-of-bounds you get the first/last index instead?
- coldtea 5y agoOr you get an Optional and you have to check if there's an error or you go the character within the range? Sounds perfect safe to me...
- saagarjha 5y agoI don't think Swift has a clamping function in the standard library, unfortunately, so we'll have to roll one ourselves. One question remains of what should be done for the empty string; I've chosen to return nil for this case. extension String { func character(atClampedIndex index: Int) -> Character? { guard !self.isEmpty else { return nil } let clamped = max(0, min(index, count - 1)) return self[self.index(startIndex, offsetBy: clamped)] } }
- saagarjha 5y ago> Things like `.reversed()`, `.sorted(), and `.shuffled()` all work trivially correctly too (since you're not operating on a bag of bytes), and it's exceedingly rare that user input will confound the operations you might need to perform. One thing to note: aside from programming interviews, these operations are fairly rare. And that's a good thing, because none of these produce results that are very intuitive, because they are not very well defined on strings in general (I don't fault Swift for this, but it's just a general problem with text). Using any of these to create a new String may cause entirely new characters to show up, or the length of the text to change. So Swift actually doesn't expose these as "string" operations, but operations on the characters themselves; in each case returning a new collection of characters that is not a String. Now, you can reconstitute them into a String pretty easily, but you should keep the this in mind when doing so.
- duped 5y agoI use these operations on a daily basis, not in interviews. If you're ingesting third party data somehow (even if it's structured like JSON or XML) there are going to be cases where you need to hand roll a simple parser.
- uranusjr 5y agoI’m genuinely very interested in the kind of data you’re dealing with. It’s common to need to reorder a list of strings, but I’ve personally never had any use case that requires me to reverse or sort _characters in a string_ to consume any kind of data (some kind of decoding, perhaps, but those tend to work better implemented at the byte array level, not string).