Swift Programming from Scratch
The book is updated for Swift 3 and the Swift Sandbox is integrated, making the exercises interactive. Read more about the book here.
Chapter 5: Strings
A string is an ordered collection of characters, such as "We ❤ Swift"
or "eat, sleep, code, repeat!"
. In Swift strings are represented by the String
type which is a collection of values of Character
type.
Creating strings
You can include predefined String
values within your code as string literals. A string literal is a fixed sequence of textual characters surrounded by a pair of double quotes (“”).
let aString = "Hello"
Take note of a special case of string, the empty string.
var emptyString = "" // empty string literal
You can create a new string by concatenating two strings using the +
operator.
let newString = "Hello" + " swift lovers" // "Hello swift lovers"
String interpolation can also be used to combine strings. By using the \(<value>)
syntax inside a string literal.
let bat = "BAT"
let man = "MAN"
// "BATMAN" - \(bat) will be replaced with "BAT" and \(man) with "MAN"
let batman = "\(bat)\(man)"
print("\(bat) + \(man) = \(batman)")
// "BAT + MAN = BATMAN"
Characters
In some cases you will want to work with the individual characters that make up the string. To do that you can use thefor-in syntax. A string exposes the list of characters with the characters
property.
var someString = "this string has 29 characters"
for character in someString.characters {
// to convert a Character into a String use string interpolation
// you will need to do this in order to compare characters
var characterAsString = "\(character)"
print(characterAsString)
}
To see how many character a string has we can use the count
property on the characters
property of the string.
var string = "This string has 29 characters"
print(string.characters.count) // 29
Comparing
You can compare string using the same operators as numbers, but usually you only care about equality.
"We ❤ Swift" == "We ❤ Swift" // true
"We ❤ Swift" == "we ❤ swift" // false - string comparison is case sensitive
"We ❤ Swift" != "We ❤ Swift" // false
"We ❤ Swift" != "we ❤ swift" // true
5.1 Full name
You are given the firstName
and lastName
of a user. Create a string variable called fullName
that contains the full name of the user.
Input:
var firstName = "Andrei"
var lastName = "Puni"
Output:
"Andrei Puni"
Input:
var firstName = "Steve"
var lastName = "Jobs"
Output:
"Steve Jobs"
Use string concatenation or use string interpolation.
var firstName = "Andrei"
var lastName = "Puni"
var fullName = firstName + " " + lastName
var firstName = "Andrei"
var lastName = "Puni"
var fullName = "\(firstName) \(lastName)"
5.2 Sum
You are given two numbers a
and b
. Compute the sum of a
and b
and create a string stored in a variable namedformattedSum
that contains the sum
written like bellow:
For a = 2 and b = 5
formattedSum = "2 + 5 = 7"
For a = 12 and b = 19
formattedSum = "12 + 19 = 31"
Input:
var a = 14
var b = 19
Expected values:
formattedSum = "14 + 19 = 31"
Input:
var a = 12345
var b = 98765
Expected values:
formattedSum = "12345 + 98765 = 111110"
Use string interpolation.
var a = 14
var b = 23
var sum = a + b
var formattedSum = "\(a) + \(b) = \(sum)"
5.3 Replace
You are given a string stored in the variable aString
. Create new string named replacedString
that contains the characters of the original string with all the occurrences of the character "e"
replaced by "*"
.
Input:
var aString = "Replace the letter e with *"
Expected values:
replacedString = "R*plac* th* l*tt*r * with *"
Input:
var aString = "Replace the letter e with *"
Expected values:
replacedString = "R*plac* th* l*tt*r * with *"
Input:
var aString = "eeee eeee"
Expected values:
replacedString = "**** ****"
Input:
var aString = "Did you know that Kathy is throwing a party tonight?"
Expected values:
replacedString = "Did you know that Kathy is throwing a party tonight?"
Create replacedString
step by step by iterating over the characters ofaString
var aString = "Replace the letter e with *"
var replacedString = ""
for character in aString.characters {
var char = "\(character)"
if char == "e" {
replacedString = replacedString + "*"
} else {
replacedString = replacedString + char
}
}
5.4 Reverse
You are given a string stored in variable aString
. Create a new string called reverse
that contains the original string in reverse order. Print the reversed string.
"Hello" -> "olleH"
"We ❤ Swift" -> "tfiwS ❤ eW"
Input:
var aString = "Hello"
Expected values:
reverse = "olleH"
Output:
"olleH"
Input:
var aString = "We ❤ Swift"
Expected values:
reverse = "tfiwS ❤ eW"
Output:
"tfiwS ❤ eW"
Input:
var aString = "this string has 29 characters"
Expected values:
reverse = "sretcarahc 92 sah gnirts siht"
Output:
"sretcarahc 92 sah gnirts siht"
Convert each character into a string and join them in reverse order.
var aString = "this string has 29 characters"
var reverse = ""
for character in aString.characters {
var asString = "\(character)"
reverse = asString + reverse
}
print(reverse)
//sretcarahc 92 sah gnirts siht
5.5 Palindrome
Print true
if aString
is a palindrome, and false
otherwise. A palindrome is a string which reads the same backward or forward.
Input:
var aString = "anutforajaroftuna"
Output:
true
Input:
var aString = "Hello"
Output:
false
Input:
var aString = "HelloolleH"
Output:
true
How can reversing a string help here ?
let aString = "anutforajaroftuna"
var reverse = ""
for character in aString.characters {
var char = "\(character)"
reverse = char + reverse
}
print(aString == reverse)
5.6 Words
Input:
var problem ="split this string into words and print them on separate lines"
Output:
split
this
string
into
words
and
print
them
on
separate
lines
Iterate over the characters in the string. Keep track of the longest word you’ve encountered so far.
var problem = "split this string into words and print them on separate lines"
var word = ""
for character in problem.characters {
if character == " " {
print(word)
word = ""
} else {
word += "\(character)"
}
}
// don't forget the last word
print(word)
// split
// this
// string
// into
// words
// and
// print
// them
// on
// separate
// lines
5.7 Long word
Input:
var problem = "find the longest word in the problem description"
Output:
description
Keep track of the longest word you encounter and also keep track of it’s length.
var problem = "find the longest word in the problem description"
// this will help the algorithm see the last word
problem += " "
var word = ""
var length = 0
var max = 0
var longestWord = ""
for character in problem.characters {
if character == " " {
if length > max {
max = length
longestWord = word
}
word = ""
length = 0
} else {
word += "\(character)"
length += 1
}
}
print(longestWord)
5.8 Magic Time!
Use this magic * operator to solve the next challenge:
func *(string: String, scalar: Int) -> String {
let array = Array(repeating: string, count: scalar)
return array.joined(separator: "")
}
print("cat " * 3 + "dog " * 2)
// cat cat cat dog dog
var newLine = "\n" * 2
print(newLine)
//
//
By using only one print()
statement draw a rectangle of size N x M
out of asterisks.
Input:
var N = 5
var M = 10
Output:
**********
**********
**********
**********
**********
Input:
var N = 2
var M = 2
Output:
**
**
Input:
var N = 5
var M = 2
Output:
**
**
**
**
**
This problem can be solved by applying the magic operator exactly 2
times.
func *(string: String, scalar: Int) -> String {
let array = Array(repeating: string, count: scalar)
return array.joined(separator: "")
}
var newLine = "\n"
var N = 5
var M = 10
var line = "*" * M
line += newLine
var rectangle: String = line * N
print(rectangle)
// **********
// **********
// **********
// **********
// **********
Swift Programming from Scratch
Read more about the book here.
?You can buy Training app + the PDF and ePub versions of the book!


Feel free to ask any questions in the comments bellow.
Hi. Thanks a lot for the exercises. They are simple enough to be rapidly understood and therefore very useful. By the way, does playground generate some kind of “derived data” which should be deleted from time to time ?
I have no idea
– my hunch is no, since it recompiles and runs the code with every change.
Thank you so much for helping us out!
What exactly is: +=
I’m new to programming and trying to learn Swift as my first language
Thank you!
a += b is shorthand for a = a + b
I’ve been managing projects in software for over 20 years and have finally decided to learn how to code. Thank you very much for this fantastic site. It’s a game working through the exercises.
Here’s a 1-line solution to your last problem.
func *(string: String, scalar: Int) -> String {
let array = Array(count: scalar, repeatedValue: string)
return “”.join(array)
}
var w = 5
var h = 10
println(((” * ” * w) + “\n”) * h)
The Replace Question in string is not correct.
Where does that “result” came from?
This is the full solution for that problem.
var aString = “Replace the letter e with *”
var replacedString = “”
for scalar in aString.unicodeScalars {
var char = “\(scalar)”
if char == “e” {
replacedString = result + “*”
} else {
replacedString = result + char
}
}
Actually you where right.
var aString = “Replace the letter e with *”
var replacedString = “”
for scalar in aString.unicodeScalars {
var char = “\(scalar)”
if char == “e” {
replacedString = replacedString + “*”
} else {
replacedString = replacedString + char
}
}
problem 5.4 reverse
i quite a bit confuse about the last line of the solution ( even your solution was right) is:
reverse = asString + reverse
for example 1:
as the 1st loop running, the variable asString would be equal to ” H” while variable reverse still blank then when the last line executed , variable reverse will be fetched in value equal to “H”, then again and again.
so i think the result will be ” Hello” as well.
furthermore: 3 = 1 + 2 same as 3 = 2 +1.
so :
1st loop: reverse = “”+ “H” same as reverse = “H” +””
there two equation still have same result right ?
can you explain why my thinking went wrong pls ? explain the working mechanism of this solution ( hope that you dont mind)
“a” + “b” = “ab”
but
“b” + “a” = “ba”
Why do you need to use unicodedScaler? Everything works without it.
Alternate way to solve 5.7 Long Word
var problem = “find the longest word in the problem description”
var word = “”
var longest = “”
problem += ” ”
for x in problem {
if x != ” ” {
word += “\(x)”
} else {
if countElements(word) > countElements(longest) {
longest = word }
word = “”
}
}
println(longest)
Magic Time can be solved with 1 line of code
func *(string: String, scalar: Int) -> String {
let array = Array(count: scalar, repeatedValue: string)
return “”.join(array)
}
var N = 5
var M = 11
var newLine = “\n”
println((“*” * M + newLine) * N)
I don’t understand why Swift let us use this as an infix operator :
func *(string: String, scalar: Int) -> String {
let array = Array(count: scalar, repeatedValue: string)
return “”.join(array)
}
println(“cat ” * 3 + “dog ” * 2)
// cat cat cat dog dog
Is that because * is already an infix operator for Int, Double, Float, etc. and we’re just extending its accepted input types?
Because while I can’t do that :
func a(a:Int,b:Int) -> Int {
return a + b
}
3 a 5
// ERROR
… this works fine :
func *(a:Bool,b:Bool) -> Bool {
return a && b
}
true * false
// false
func +(a:Bool,b:Bool) -> Bool {
return a || b
}
true + false
// true
Please answer
Custom operators can begin with one of the ASCII characters /, =, -, +, !, *, %, < , >, &, |, , or ~, or any of the Unicode characters in the “Math Symbols” character set. – from Swift Operators
Ok but why don’t we have to first declare the operator beforehand ?
infix operator * { /*…*/ }
Is this because it’s already declared as it’s default for multiplication ?
I’m pretty sure thats the reason.
Thanks for your answers !
I have been making functions out of these problems so I can reuse them. Here is an example of the longest word exercise.
func findLongest(testString:String) ->String {
var wTestString = testString + ” ”
var tmpHolder = “”
var tCount = 0
var theBiggest = “”
for scalar in wTestString.unicodeScalars {
var myCharAsString2 = “\(scalar)”
if myCharAsString2 != ” “{
tmpHolder += myCharAsString2
} else {
if countElements(tmpHolder) >= tCount{
theBiggest = tmpHolder
tCount = countElements(tmpHolder)
}
tmpHolder = “”
}
}
return theBiggest
}
var myProblem = “find the longest word in the problem description”
findLongest(myProblem)
That seems helpful :). A lot of the problems from the book are problems you face every day as a developer.
For section 5.3 (Replace), you could also do this:
let aString = “Replace the letter e with *”
let replaced = String(map(aString.generate()) {
$0 == “e” ? “*” : $0
})
println(“\(replaced)”)
Hey, UnicodeScalars is
var someString = “this string has 29 characters”
for scalar in someString.unicodeScalars {
// to convert a UnicodeScalar into a String use string interpolation
// you will need to do this in order to compare characters
var characterAsString = “\(scalar)”
println(characterAsString)
}
and we can even directly give in this way
for i in astring{
println(i)
}
Is it both are same or different. if so Explain it please
I copied your example exactly for”countElements” gives me an error, but the function “count” does not. I am I using a different version of swift than you or something?
Nevermind, I am indeed using a newer version! And Swift 2 has further changed the syntax to something like “test1.characters.count” apparently.
For 5.3, examples 1 and 2 are exactly the same! (I compared them with the “==” operator ;))
Thank you for spotting that
For the reversed characters check I use the following method. The built in functions in Swift are actually very useful.
let aString = “anutforajaroftuna”
var reverse = String(aString.characters.reverse())
if aString == reverse {
print(“True”)
} else {
print(“False”)
}