Collection slicing and indices in Swift - Time & Space Complexity
When working with collections in Swift, slicing lets us take parts of the collection. Understanding how long slicing takes helps us write faster code.
We want to know: how does the time to slice grow as the collection gets bigger?
Analyze the time complexity of the following code snippet.
let numbers = Array(1...1000)
let slice = numbers[100..<200]
for number in slice {
print(number)
}
This code creates an array of numbers, takes a slice from index 100 to 199, then prints each number in the slice.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Looping through the slice to print each number.
- How many times: The loop runs once for each element in the slice (100 times here).
Explain the growth pattern intuitively.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 |
| 100 | 100 |
| 1000 | 1000 |
Pattern observation: The number of operations grows directly with the slice size. Double the slice size, double the work.
Time Complexity: O(n)
This means the time to process the slice grows linearly with the number of elements in the slice.
[X] Wrong: "Slicing an array is instant and costs no time."
[OK] Correct: While slicing itself is fast, using the slice (like looping through it) takes time proportional to the slice size.
Knowing how slicing and indexing affect time helps you explain your code choices clearly and shows you understand how data size impacts performance.
"What if we changed the slice to a filter that picks elements based on a condition? How would the time complexity change?"
Practice
let numbers = [10, 20, 30, 40, 50]For example,
numbers[1...3] returns which part of the array?Solution
Step 1: Understand collection slicing syntax
The syntaxnumbers[1...3]means take elements from index 1 to index 3, including both ends.Step 2: Identify the elements in the slice
Indexes 1, 2, and 3 correspond to values 20, 30, and 40 respectively.Final Answer:
A part of the collection from index 1 to 3 inclusive -> Option AQuick Check:
Slice [1...3] = [20, 30, 40] [OK]
- Thinking slicing returns a single element
- Assuming slicing reverses the collection
- Believing slicing causes an error
items from index 2 to 5 (inclusive)?Solution
Step 1: Understand Swift range operators
The closed range operator...includes both start and end indexes, so2...5means indexes 2, 3, 4, and 5.Step 2: Evaluate the slicing syntaxes
items[2..<5]uses half-open range which excludes index 5.items.slice(2, 5)calls a non-existent method.items[2,5]is invalid syntax.items[2...5]is correct.Final Answer:
items[2...5] -> Option CQuick Check:
Closed range includes end index [OK]
- Using half-open range when inclusive is needed
- Using comma inside brackets incorrectly
- Trying to call slice() method which doesn't exist
let fruits = ["apple", "banana", "cherry", "date", "fig"]What is the output of this code?
let slice = fruits[1..<4]
print(slice)Solution
Step 1: Understand half-open range slicing
The range1..<4includes indexes 1, 2, and 3 but excludes 4.Step 2: Identify elements at these indexes
Indexes 1, 2, 3 correspond to "banana", "cherry", and "date".Final Answer:
["banana", "cherry", "date"] -> Option AQuick Check:
Half-open range excludes last index [OK]
- Including the element at index 4 mistakenly
- Confusing half-open with closed range
- Expecting a runtime error for valid slice
let letters = ["a", "b", "c", "d"]
let slice = letters[1...4]What is the problem with this code?
Solution
Step 1: Check array bounds
The array has indexes 0 to 3. Index 4 does not exist.Step 2: Understand slicing with out-of-bounds index
Using1...4tries to access index 4, which causes a runtime error.Final Answer:
Index 4 is out of range causing a runtime error -> Option BQuick Check:
Accessing invalid index causes error [OK]
- Assuming slicing auto-adjusts out-of-range indexes
- Thinking syntax is wrong instead of index error
- Expecting empty slice instead of error
let data = [5, 10, 15, 20, 25, 30]You want to create a slice that includes every element except the first and last. Which code correctly creates this slice?
Solution
Step 1: Determine indexes to include
Exclude first (index 0) and last (index 5) elements, so include indexes 1 to 4.Step 2: Use half-open range for slicing
Using1.. means indexes 1 up to but not including 5, which is indexes 1 to 4.Final Answer:
let slice = data[1.. -> Option DQuick Check:
Half-open range excludes last index [OK]
- Using closed range which includes the last index
- Using count directly as upper bound causing out-of-range
- Confusing inclusive and exclusive ranges
Ready to prove it?
Pass the test and this pattern moves unknown
