Skip to content
Lesson 10 of 15

Step 1 of 5 · Reading · ~3 min

Learn

Collections

Arrays

An Array is an ordered, growable, single-type sequence — and, like everything else in Swift's standard library, a value type.

var nums = [1, 2, 3, 4]

print(nums.count)
print(nums[0])
print(nums.isEmpty)

//> 4
//> 1
//> false

The type of nums is [Int], inferred from the literal. Write it yourself when there is no literal to infer from:

var empty: [Int] = []
var alsoEmpty = [Int]()
var zeros = Array(repeating: 0, count: 3)
print(empty, alsoEmpty, zeros)

//> [] [] [0, 0, 0]

Growing and shrinking

var nums = [1, 2, 3, 4]
nums.append(5)
nums.insert(0, at: 0)
let removed = nums.removeFirst()
nums.removeLast()
print(removed, nums, nums.contains(3))

//> 0 [1, 2, 3, 4] true

removeFirst() and removeLast() return the element they took out, which is handy and easy to miss. All of these need var — an array bound with let is frozen, contents included.

Indexing is unchecked

This is the one way an array will kill your program:

let nums = [1, 2, 3]
print(nums[5])          // crashes: Index out of range

There is no nil, no default, no exception to catch. The subscript trusts you. The safe alternatives all return optionals instead:

UnsafeSafeReturns
nums[0]nums.firstInt?
nums[nums.count - 1]nums.lastInt?
nums[i]nums.indices.contains(i) firstBool
let nums = [1, 2, 3]
print(String(describing: nums.first))
print(nums.indices.contains(9))
print(String(describing: [Int]().first))

//> Optional(1)
//> false
//> nil

min() and max() are optionals too

An empty array has no maximum, so max() cannot promise an Int:

print(String(describing: [3, 8, 2].max()))
print(String(describing: [Int]().max()))

//> Optional(8)
//> nil

This matters more than it looks — see the exercise below.

Sorting: two methods, one letter apart

var nums = [3, 1, 2]
let ascending = nums.sorted()
let descending = nums.sorted(by: >)
nums.sort()
print(ascending, descending, nums)

//> [1, 2, 3] [3, 2, 1] [1, 2, 3]

sorted() returns a new array and leaves the original alone. sort() mutates in place and returns nothing. Swift's naming convention holds across the library: the -ed / -ing form is the non-mutating one.

Arrays are values

var a = [1, 2, 3]
var b = a
b.append(4)
print(a, b)

//> [1, 2, 3] [1, 2, 3, 4]

b is a copy, not an alias. Coming from Python or Java this is the single biggest behavioural difference — there, b.append(4) would have changed a too. Swift only performs the physical copy when one side is actually mutated, so the safety is close to free.

Your exercise

Read a line of space-separated integers and print the largest.

The mistake the grader catches is printing the optional. nums.max() has type Int?, so print(nums.max()) compiles — with a warning that the value was implicitly coerced to Any — and prints Optional(9) where the test wants 9. Unwrap it: nums.max()! is acceptable here because the input always has at least one number, and nums.max() ?? 0 is the habit worth building. Watch the hidden test too: it feeds -3 -1 -7, so any solution that starts a running maximum at 0 reports 0 instead of -1.

Up nextDictionaries and SetsCollections

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…