Skip to content
Theory · Strings and characters · lesson 6 of 7

String methods

There is more to do with a string of beads than count it. You can rethread it in capital letters, look for certain beads on it, cut it into pieces at separator beads and put the pieces back together.

Here is a task that needs this. A user sent the file Photo.PNG, and the program accepts only PNG pictures, checking that the name ends with .png. The name came with capital letters, and a direct check doesn't recognize it. The program below shows both the problem and the fix:

SWIFT
let file = "Photo.PNG"
let name = file.lowercased()
print(name, file.uppercased()) // photo.png PHOTO.PNG
print(name.hasPrefix("photo"), name.hasSuffix(".png")) // true true
print(file.hasSuffix(".png"), file.contains("Photo")) // false true
print(file) // Photo.PNG

Actions a string can perform by itself are called methods. A method is a function that belongs to the string. You call it with a dot and pass what it needs in parentheses: name.hasSuffix(".png").

Letter case

A letter is either capital or small — that is its case. Two strings that differ only in case are different for Swift: "PNG" == "png" gives false.

  • lowercased() returns a copy of the string in small letters: photo.png.
  • uppercased() returns a copy in capital letters: PHOTO.PNG.

Both methods return a new string, and the original doesn't change. That's why the last line of the program prints Photo.PNG, as before.

To compare strings ignoring case, bring both to the same case. A user's answer is checked like this: answer.lowercased() == "yes", and then both Yes and YES match.

Searching a string

Three methods answer the question "does the string have this text" and return a Bool:

  • hasPrefix("photo") — whether the string starts with this text;
  • hasSuffix(".png") — whether it ends with it;
  • contains("Photo") — whether this text is anywhere inside.

All three tell cases apart. file.hasSuffix(".png") gives false, because file ends with .PNG. So the check is done on name, where all the letters are already small.

Splitting and joining

A comma-separated list in a string often has to be cut into pieces and then put back together, with another separator:

SWIFT
let list = "tea,milk,,bread"
let items = list.split(separator: ",")
print(items.count) // 3
print(items.joined(separator: " + ")) // tea + milk + bread

split(separator:) — cutting

split cuts the string at every separator character, here at the comma. It returns an array of pieces — a row of string pieces in order, and items.count gives the number of pieces.

Between two commas in a row the piece is empty, and split drops it. That's why there are three pieces, not four. Empty pieces at the start and at the end of the string are dropped the same way: ",a," gives one piece.

joined(separator:) — joining

joined puts the pieces into one string and inserts the separator between them. There is no separator after the last piece, so the program prints tea + milk + bread.

Here the bead picture is inaccurate. A real string can't be made whole again after it is cut. But split doesn't touch list: afterwards the string is still whole, and you can cut it again.

A string backwards

reversed() goes through the characters of a string from the end. On its own it doesn't return a string, so String(…) builds a new string from these characters:

SWIFT
let word = "stressed"
print(String(word.reversed())) // desserts

The characters are moved whole, not byte by byte. String("café".reversed()) gives éfac, and the letter é stays whole.

Reversing a string is a common interview task, for example to check for a palindrome — a word that reads the same both ways. In Swift that check takes one line: word == String(word.reversed()).

Common mistake

The string was reversed, but String(…) was forgotten:

SWIFT
print(word.reversed()) // ✗

The program compiles without warnings, but instead of desserts it prints an internal record like ReversedCollection<String>(_base: "stressed"). reversed() doesn't build a new string, and print shows what it got as it is. Wrap the result in String(…).

Key points

  • lowercased() and uppercased() return a new string in another case, and the original doesn't change.
  • hasPrefix, hasSuffix and contains search a string for text and tell cases apart.
  • split(separator:) cuts a string into pieces and drops the empty ones, and joined(separator:) joins pieces, putting the separator only between them.
  • String(s.reversed()) reverses a string character by character; without String(…) you don't get a string.