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:
| Unsafe | Safe | Returns |
|---|---|---|
nums[0] | nums.first | Int? |
nums[nums.count - 1] | nums.last | Int? |
nums[i] | nums.indices.contains(i) first | Bool |
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.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…