Chapter 42: Swift Ranges
1. What is a Range in Swift?
A range represents a sequence of consecutive values — usually integers, but it can work with other types too.
Think of a range as answering the question:
“Give me all the numbers from A to B (or up to but not including B)”
Swift has four main kinds of ranges:
| Range Type | Syntax | Includes both ends? | Most common use case | Example values (when 3…7) |
|---|---|---|---|---|
| Closed Range | a…b | Yes (includes b) | Loops that include the last value | 3,4,5,6,7 |
| Half-Open Range | a..<b | No (excludes b) | Array indices, 0-based counting | 3,4,5,6 |
| One-Sided (open to right) | a… | Includes everything from a onward | Suffix of array, from some index to end | 3,4,5,6,7,8,… |
| One-Sided (open to left) | …b | Includes everything up to b (inclusive) | Prefix of array, up to some index | …,-1,0,1,2,3 (up to 3) |
2. Creating & Using the Most Common Ranges
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// 1. Closed range (... ) – includes both ends for number in 1...5 { print(number) // 1 2 3 4 5 } // 2. Half-open range (..<) – very common with arrays let fruits = ["Mango", "Banana", "Apple", "Orange", "Guava"] for i in 0..<fruits.count { print("Fruit \(i+1): \(fruits[i])") } // 3. One-sided range (from some point to end) let recentFruits = fruits[2...] print(recentFruits) // ["Apple", "Orange", "Guava"] // 4. One-sided range (everything up to some point) let earlyFruits = fruits[...2] print(earlyFruits) // ["Mango", "Banana", "Apple"] |
3. Ranges in Real-Life Situations (examples you will actually write)
Example 1 – Pagination / Showing one page of results
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
let allProducts = Array(1...50) // imagine 50 items let pageSize = 10 let pageNumber = 3 // user clicked page 3 (1-based) let start = (pageNumber - 1) * pageSize let end = min(start + pageSize, allProducts.count) let pageItems = allProducts[start..<end] print("Page \(pageNumber) (items \(start+1) to \(end)):") for item in pageItems { print(" • Product #\(item)") } |
Example 2 – Grade / score ranges (very common in apps)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
let score = 87 let grade: String = switch score { case 90...100: "A+" case 80..<90: "A" case 70..<80: "B" case 60..<70: "C" case 0..<60: "Needs improvement" default: "Invalid" } print("Score \(score) → Grade: \(grade)") // Score 87 → Grade: A |
Example 3 – Showing “recent” items
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
let recentSearches = [ "Swift arrays", "String interpolation", "forEach vs for-in", "Array slice", "SwiftUI List", "Ranges in Swift" ] let howManyRecent = 4 let recent = recentSearches.suffix(howManyRecent) print("Recent searches:") for (index, query) in recent.enumerated() { print(" \(index + 1). \(query)") } |
Example 4 – Processing data in chunks / batches
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
let largeList = Array(1...25) let batchSize = 6 for start in stride(from: 0, to: largeList.count, by: batchSize) { let end = min(start + batchSize, largeList.count) let batch = largeList[start..<end] print("Batch starting at \(start): \(batch)") } |
4. Ranges with Non-Integer Types (possible but less common)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// Character range for letter in Character("A")...Character("F") { print(letter) // A B C D E F } // String range (works, but rarely used directly) let names = ["Aarav", "Priya", "Rahul", "Sneha"] let slice = names["P"...] // from "Priya" to end (lexical order) print(slice) // ["Priya", "Rahul", "Sneha"] |
5. Very Common Beginner Mistakes & Correct Habits
| Mistake | Wrong / Dangerous code | Correct / Better habit | Why? |
|---|---|---|---|
| Using … when you want up to but not including | for i in 0…9 { print(arr[i]) } | for i in 0..<arr.count { … } | … includes last index → crash |
| Assuming slice starts at index 0 | let s = arr[3…6]; print(s[0]) | print(s[s.startIndex]) or s.first | Slice has its own startIndex |
| Using closed range with array indices | arr[0…5] (when count=5) | arr[0..<5] or arr[0…4] | 0…5 tries to access index 5 → crash |
| Keeping large slice forever | let slice = bigArray[0..<1000]; bigArray = [] | let copy = Array(slice) | Slice keeps entire original array alive |
| Confusing ..< and … | for i in 1…10 { print(arr[i]) } | for i in 0..<arr.count { print(arr[i]) } | Off-by-one errors |
6. Quick Reference – Most Used Range Patterns
| Goal | Best expression | Returns type | Safe? | Common use case |
|---|---|---|---|---|
| Loop including last value | for i in 1…10 { … } | — | Yes | 1-based counting |
| Loop over array indices | for i in 0..<array.count { … } | — | Yes | Classic array access |
| Get first N items | array.prefix(N) or array[..<N] | ArraySlice | Yes | Show preview / recent items |
| Get last N items | array.suffix(N) | ArraySlice | Yes | Recent searches, last messages |
| Everything after index X | array[X…] | ArraySlice | Yes | Show from current position onward |
| Everything up to index X (inclusive) | array[…X] | ArraySlice | Yes | Show items before current |
| Paginate / show page | array[start..<end] | ArraySlice | Yes | TableView / List pagination |
| Convert slice to full array | Array(slice) | [Element] | Yes | When you want to release memory |
7. Small Practice – Try these
- Create array of numbers 1…20 → Print items 5 to 12 (inclusive) using closed range → Print items 3 to end using one-sided range
- Create array of 10 task names → Show only last 4 tasks using suffix(4) → Number them as “Recent 1: …”, “Recent 2: …”, etc.
- Create array of 15 names → Show items from index 4 to 10 (inclusive) → Use both range slice and enumerated() to print them with numbers
Paste your code here if you want feedback or better ways!
What would you like to explore next about arrays?
- Sorting arrays (simple & custom comparators)
- Filtering, mapping, reducing in depth
- Array slicing pitfalls & memory lifetime
- Multidimensional arrays (2D tables, grids…)
- Arrays in SwiftUI (List, ForEach, @State, animations…)
- Or move to another topic (dictionaries, sets, optionals…)
Just tell me — we’ll continue in the same clear, detailed, patient style 😊
