Article 2: Swift 101 — Control Flow & Data Structures in Swift
Welcome to the second article in our Swift development series! In this installment, we’ll explore control flow (if statements, loops, and functions) and dive into the key data structures in Swift, such as arrays, dictionaries, and sets.
Control Flow: Making Decisions and Repeating Code
Control flow structures allow your code to make decisions and repeat tasks, which are fundamental to any program. But remember: clean, readable control structures are the backbone of robust code. Avoid convoluted logic at all costs. Your goal should always be to write clear, expressive code that is easy to understand and maintain.
1. Conditionals (if/else)
Conditionals are used to execute blocks of code based on certain conditions. The most common conditional structure is the if
statement.
Here’s a simple example:
let temperature = 22
if temperature > 30 {
print("It's hot outside!")
} else {
print("The weather is nice.")
}
In the code above:
- The condition checks whether the
temperature
is greater than 30. If it is, the first block of code runs. If it’s not, theelse
block runs. - You can also chain multiple conditions using
else if
:
if temperature > 30 {
print("It's hot outside!")
} else if temperature > 20 {
print("The weather is nice.")
} else {
print("It's a bit chilly.")
}
2. Switch Statements
In Swift, the switch
statement is a powerful alternative to multiple if/else
conditions. It allows for more complex matching and is often cleaner.
let score = 85
switch score {
case 90...100:
print("A grade!")
case 80..<90:
print("B grade!")
case 70..<80:
print("C grade!")
default:
print("Failing grade")
}
In this example, the switch
statement checks the score
and prints a message based on the grade range. Notice how you can use ranges (e.g., 90...100
).
3. Loops: Repeating Code
Loops are useful when you want to repeat a block of code multiple times.
- For-in Loop: This loop is great when you want to iterate over a collection (like an array or a range of numbers).
let fruits = ["Apple", "Banana", "Orange"]
for fruit in fruits {
print(fruit)
}
- While Loop: This loop continues as long as a condition is
true
.
var counter = 0
while counter < 5 {
print("Counter is \(counter)")
counter += 1
}
- Repeat-While Loop: This is similar to the
while
loop, but it ensures the loop body is executed at least once, regardless of the condition.
var counter = 0
repeat {
print("Counter is \(counter)")
counter += 1
} while counter < 5
4. Functions: Organizing Your Code
Functions allow you to group related code together for reuse and organization. They are the building blocks of modular code.
Here’s how you define a basic function in Swift:
func greet(name: String) -> String {
return "Hello, \(name)!"
}
let greeting = greet(name: "Hafizi")
print(greeting) // Output: Hello, Hafizi!
- The function
greet(name:)
takes a parameter (name: String
) and returns aString
. - We use parameter labels (the
name
label ingreet(name:)
) to make the function call more descriptive.
You can also have functions without return values:
func sayHello() {
print("Hello!")
}
Data Structures in Swift: Working with Collections
Now, let’s move on to data structures — the collections that help store and manage data. Swift provides three essential types for this: arrays, dictionaries, and sets.
1. Arrays: Ordered Collections
An array is an ordered collection of values, and each value can be accessed by its index.
var numbers = [1, 2, 3, 4, 5]
numbers.append(6) // Adds 6 to the end
numbers[0] // Access the first element (1)
numbers.remove(at: 2) // Removes the element at index 2 (3)
Arrays are ordered, meaning the position of each element matters. You can loop through an array like this:
for number in numbers {
print(number)
}
2. Dictionaries: Key-Value Pairs
A dictionary is an unordered collection of key-value pairs. It’s useful when you need to store data where each value is associated with a unique key.
var person = ["name": "Ali", "age": 28]
person["name"] // Accesses the value for the key "name"
person["age"] = 29 // Modifies the value for the key "age"
person["gender"] = "Male" // Adds a new key-value pair
To loop through a dictionary:
for (key, value) in person {
print("\(key): \(value)")
}
3. Sets: Unordered Collections of Unique Values
A set is an unordered collection of unique values. It’s useful when you want to store distinct items and don’t care about the order.
var numbersSet: Set = [1, 2, 3, 4, 5]
numbersSet.insert(6) // Adds a new element
numbersSet.remove(4) // Removes the element 4
You can perform set operations like union, intersection, and difference:
let setA: Set = [1, 2, 3, 4]
let setB: Set = [3, 4, 5, 6]
let union = setA.union(setB) // [1, 2, 3, 4, 5, 6]
let intersection = setA.intersection(setB) // [3, 4]
let difference = setA.subtracting(setB) // [1, 2]
Strong Opinion: Write Clean, Readable Control Structures
As we’ve seen, Swift’s control flow and data structures are powerful, but they can quickly become messy if not used thoughtfully. Clean, readable control structures are the backbone of robust code. Avoid writing convoluted logic that’s hard to follow. Here are some quick tips for maintaining readability:
- Keep conditionals simple: If your
if
statements are getting too long or complicated, consider refactoring them into smaller, more manageable functions. - Don’t nest too deeply: If you find yourself nesting
if
statements or loops too many levels deep, it’s a red flag. Consider breaking your code into smaller functions. - Use early exits: Instead of wrapping large blocks of code in
else
statements, try usingreturn
orcontinue
early in your function to exit as soon as possible when certain conditions are met.
Real-World Example: A Simple Grocery List App
Let’s put it all together with a simple app that manages a grocery list. The app will allow us to add items to the list and check for duplicates.
var groceryList: Set<String> = []
// Function to add an item to the grocery list
func addItem(item: String) {
if groceryList.contains(item) {
print("\(item) is already on the list.")
} else {
groceryList.insert(item)
print("\(item) added to the list.")
}
}
// Adding items
addItem(item: "Apple")
addItem(item: "Banana")
addItem(item: "Apple") // Duplicate item
// Print the list
print(groceryList)
In this example:
- We use a set to store the grocery list, ensuring all items are unique.
- The
addItem
function checks if an item is already in the set, ensuring no duplicates.
Conclusion
In this article, we covered the basics of control flow and data structures in Swift, two essential concepts for writing efficient and readable code. Remember, clean, readable control structures make your code more maintainable and less error-prone, so take the time to write clear logic.
Next up: Article 3: Functions, Closures, and Optionals — we’ll explore more advanced topics that will take your Swift skills to the next level.
Stay tuned!