[swift-users] the pain of strings

Brent Royal-Gordon brent at architechies.com
Fri Jun 30 21:33:52 CDT 2017

> On Jun 30, 2017, at 2:44 PM, David Baraff via swift-users <swift-users at swift.org> wrote:
> Python:
>  shortID = longerDeviceID[-2:]		# give me the last two characters
> Swift:
>  let shortID = String(longerDeviceID.characters.dropFirst(longerDeviceID.characters.count - 2))

This actually perfectly illustrates why Swift is designed the way it is.

The first thing to notice is that the Python version is terse, but it's actually impossible to know what it actually *does*. Is it operating on bytes, code units, Unicode scalars, or grapheme clusters? Well, that depends: is this Python 2 or Python 3? If it's 2, is this a `string` or a `unicode`? If it's 3, is it a `string` or a `bytes`? And if it is one of the Unicode-aware types, how are those indexed? (I honestly don't know—I can't find anything about that in the documentation.) And forget about understanding its performance characteristics—that's an implementation detail.

The second thing to notice is that your Swift solution is very inefficient. It counts all the characters in the string, subtracts two, then counts all but the last two characters in the string before returning the last two. That is, it unnecessarily walks over the entire string twice. If you read your expression closely, all of this behavior is plainly stated in the code.

What you actually want to do is count back two characters from the *end*, like so:

	let shortID = String(longerDeviceID.characters[longerDeviceID.characters.index(longerDeviceID.characters.endIndex, offsetBy: -2) ..< longerDeviceID.characters.endIndex])

Or, in Swift 4:

	let shortID = String(longerDeviceID[longerDeviceID.index(longerDeviceID.endIndex, offsetBy: -2)...])

Or, as Adrian Zubarev pointed out, you can use the very convenient `suffix(_:)` method, available on any `Sequence`:

	let shortID = String(longerDeviceID.characters.suffix(2))	// Swift 3
	let shortID = String(longerDeviceID.suffix(2))				// Swift 4

Swift's strings were very deliberately designed this way. It's tougher to get off the ground, sure, but it's better in the long run.

Brent Royal-Gordon

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170630/ef62390f/attachment.html>

More information about the swift-users mailing list