Swift 101: Collections Part I - Arrays
Tags: learning, swift, mobile, beginners
Published: 2024-05-29 15:19:41

#<h1> Hola Mundo! </h1>
<Enter>

Welcome to a new article in a series of [Swift 101 notes](https://dev.to/silviaespanagil/swift-101-getting-into-ios-development-gji) 📝 I did while learning the language and I decided to share them because why not?.

If you're new to Swift or interested in learning more about this language, I invite you to follow my series! 🙊

In this chapter, I'll share Part I of Collections and Collection Types, where we'll dive into Arrays.
___

[A couple of weeks ago](https://dev.to/silviaespanagil/swift-101-understanding-types-variables-and-constants-l9h), we discussed constants and variables, which store values for us to use in our code and some simple types. However, there are some other complex types that we will find across our apps📱​.

As you may already guess, "Collections" are types that store many values. They arrange all those values in certain ways so we can access them in the future.

Think of it like a fruit basket with many fruits in it. Similarly, arrays in Swift store multiple values of the same type in an ordered list, like a line of apples, oranges, and bananas neatly arranged in your basket 🍎​🍊​🍌​

<Enter>
___
###Arrays
<Enter>
Arrays are **an ordered collection of values** and are the most common collection type. Inside an array, we may store any kind of elements of the same type.

Arrays are one of the most commonly used collection types in Swift due to their simplicity and efficiency. Arrays maintain an ordered list of elements. This makes them ideal for scenarios where the order of elements matters, such as lists of items or sequences of tasks.

To create an array, we separate elements with commas and enclose them in square brackets.

```
let intArray = [1, 2, 3]
let stringArray = ["Mónica", "Rachel", "Phoebe"]
```
<Enter>
___
#### Typing our arrays

As with everything in Swift, arrays are also typed. If we don’t indicate it explicitly, Swift will infer the type for us. 

However, for Swift to be able to infer the type, the values inside the array must be homogeneous, meaning all values must be of the same type. This is called **array literals**.

If we don't type our array, and the values are heterogeneous, we will get an error ❌​, and Swift will ask us to add an explicit type to ensure the mixed types are intentional.

To set a type to an array we must indicate it after the naming just as we do in simple variables and constants. 

If we want to create a heterogenous array or we don’t know which kind of values we will hold in that variable we can set the `Any` type -_not recommendable_-

Strong typing in Swift ensures that each array can only contain elements of a specific type. 

This could prevent many common programming errors and make your code more predictable and easier to debug. By specifying the type of elements Swift can also optimize performance and provide better compile-time checks.

```swift
// All values are the same type
let homogenousArray: [Double] = [1.4, 2.6, 3.7]
let alsoHomogenousArray: [String] = ["Pippin", "Merry", "Frodo", "Sam"]
```

```swift

// Values types may be different so type is Any
let heterogenousArray: [Any] = [8, "Kobe Bryant", 24.8]
```
<Enter>
___
####Classes and structs as types

Until now we have been using the most common types to type all of our values. However, while dealing with our apps, especially if they interact with APIs or complex data, we may need to manage arrays with heterogeneous types. 

If you scroll back, I said that we can use `Any` as a type, but I also said that is not a really good idea🙅🏽‍♀️​. But if Swift gives us that option, why is it not a good idea?

Typing makes our code more reliable, and safer🛟​. We know always what kind of value we are going to find in that variable. With `Any` we lose that advantage. We may also cause compilation issues, overcomplicate our code, etc.

But we can overcome this by using classes or structs as types. 

Let’s imagine that we have a newsletter and we need an array with the user name, email, and confirmation that it wants to receive an email. And we are going to store that in an Array. So first we could create a struct and then assign it as a type.

```swift
struct User: Identifiable, Hashable {
    let id: Int
    let name: String
    let email: String
    let permission: Bool
}
var registeredUsers: [User]
```

In Swift, structs and classes are both used to create complex data types, but they have some key differences. Structs are value types, which means they are copied when assigned to a new variable or constant, or when passed to a function. 

Classes, on the other hand, are reference types, so they are passed by reference and can have inheritance. 

Generally, is a better idea to use structs for simpler data types that do not require inheritance and classes for more complex types that benefit from inheritance.

✨​Further details on classes and structs will come later on in the series, so don't forget to follow me and keep an eye on new updates.✨​

<Enter>
___
###Array managing: accessing values and methods

####Accessing array values
We now know that an array, as a collection, can store one or many values, but to use them we will probably need them separated and to do so we need to access those values.

##### **Using the value index**

One way of accessing our array values is by calling the index. As arrays are **ordered collections** if nothing explicitly changes, the value in a certain position will always be the same.

```swift
let hatchNumbers = [4, 8, 15, 16, 23, 42]
let thirdHatchNumber = hatchNumbers[2]
print(thirdHatchNumber) // 15
```

🧐 Remember that the array index starts at 0. So the first value is index 0 and so on. 🧐

##### **Iterations or loops: For-in and while**
There are two ways to iterate an array. One you may use while using SwiftUI in the views and the other one the rest of the time, but don't worry, they are pretty similar. 

If you want to know more about this, keep an eye on this series because I'll be writing about Control Flow however, in the meanwhile, we will hammer the most common here: For-in loops

Loops can be imagined as a spiral, each loop of the spiral is an item. So, when we iterate an array, we circle the array over and over.

Imagine we have an array with the Fellowship of the Rings names and I want to access the name of each one of them. We could check the array using a `for in` loop and print the values.

```swift

let fellowshipMembers = ["Frodo", "Sam", "Gandalf", "Aragorn", "Legolas", "Gimli", "Boromir", "Merry", "Pippin"]

// Access elements
for member in fellowshipMembers {
  print(member)
}
```

What is going to happen is that Swift is going to check each member inside the `fellowshipMembers` array and will print the nine values.

```swift
Frodo
Sam
Gandalf
Aragorn
Legolas
Gimli
Boromir
Merry
Pippin
```

We can also do the iteration but add a clause in it. For doing so we will have to add a **where** in the loops.

```swift
// Leave Frodo out
let fellowshipMembers = ["Frodo", "Sam", "Gandalf", "Aragorn", "Legolas", "Gimli", "Boromir", "Merry", "Pippin"]
for member in fellowshipMembers where member != "Frodo" {
  print(member)
}
```
This will print all the Fellowship members but will skip Frodo.

There’s another way to do a loop by evaluating a condition, and that is using while. Basically, we ask Swift that while a condition happens, do something.

Think of it as when you are cooking, `while` you see flour, whisk the mix. Then you understand that if the flour is not visible anymore you can stop whisking.

```swift
while condition {
  do this
}
```

Let’s imagine that we want to allow Frodo to gather 3 things

```swift
var itemsToCollect = ["Ring", "Lembas Bread", "Elven Cloak", "Light of Eärendil", "Mithril Coat"]
var thingsCollected = 0

while thingsCollected < 3 {
    print("Frodo has collected: \(itemsToCollect[thingsCollected])")
    thingsCollected += 1
}
```

This will print us this

```swift
Frodo has collected: Ring
Frodo has collected: Lembas Bread
Frodo has collected: Elven Cloak
```

While we are looping an array we may want to access to the index value of the element and call the `enumerated()` method with the array. For doing so we may call the index in the loop.

```swift
// Print with index
let fellowshipMembers = ["Frodo", "Sam", "Gandalf", "Aragorn", "Legolas", "Gimli", "Boromir", "Merry", "Pippin"]
for (index, member) in fellowshipMembers.enumerated() {
  print("Member number \(index + 1): \(member)")
}
```

This will print

```swift
Member number 1: Frodo
Member number 2: Sam
Member number 3: Gandalf
Member number 4: Aragorn
Member number 5: Legolas
Member number 6: Gimli
Member number 7: Boromir
Member number 8: Merry
Member number 9: Pippin
```
🧐 Remember that the array index starts at 0. So the first value is index 0 and so on. 🧐

___
###Array methods and properties

We already know how fundamental are Arrays, they allow us to store multiple values in a single variable, making it easier to manage collections of data. 

But to truly harness the 💪​power of arrays💪​, it's essential to understand the various methods and properties that Swift provides for working with them. And that also makes it so much easier to work with them.

####What are Array Methods and Properties?
**Properties** are characteristics of an array that provide information about the array itself. For instance, properties can tell you the number of elements in an array or whether the array is empty.

**Methods** are functions that perform actions on the array. They can help you add, remove, or find elements within the array, and perform other useful operations.

By learning these methods and properties, you can effectively manipulate arrays and make your code more efficient and readable.

Let's see the most used:

####`.count`
This property counts how many elements are inside an array.

```swift
var numbers = [1, 2, 3, 4]
print(numbers.count) 
// Output: 4
```
####`.append()`
This method allows us to add new elements to **the end** of the array.

``` swift
var groceryList = ["Onions", "Apples", "Pasta"]
groceryList.append("Bread")
print(groceryList) 
// Output: ["Onions", "Apples", "Pasta", "Bread"]
```
####`.insert()`
This method allows us to add new values to the array at a specific index.

```swift
var groceryList = ["Onions", "Apples", "Pasta"]
groceryList.insert("Bread", at: 1)
print(groceryList) 
// Output: ["Onions", "Bread", "Apples", "Pasta"]
```
####`.remove(at:)`
This method removes the element at a specific index in the array.

```swift
var groceryList = ["Onions", "Apples", "Pasta"]
groceryList.remove(at: 0)
print(groceryList) 
// Output: ["Apples", "Pasta"]
```
####`.removeAll()`
This method empties the array of all its values.

```swift
var groceryList = ["Onions", "Apples", "Pasta"]
groceryList.removeAll()
print(groceryList) 
// Output: []
```
####`.filter()`
This method, filters our array. It creates a new array with the values that satisfy a condition.
For example, let's filter our array to create a new one with all the values that are less than 3.

```swift
var numbers = [1, 2, 3, 4]
let filtered = numbers.filter { $0 < 3 }
print(filtered) 
// Output: [1, 2]
```
####`.map()`
This method transforms each value of the array and returns a new array with the transformed values.

```swift
var numbers = [1, 2, 3, 4]
let mappedNumbers = numbers.map { $0 * 2 }
print(mappedNumbers) 
// Output: [2, 4, 6, 8]
```
####`.forEach()`
This method performs an action for each value in the array.

```swift
var groceryList = ["Onions", "Apples", "Pasta"]
groceryList.forEach { print($0) }
/* Output: 
   Onions
   Apples
   Pasta
*/
```
####`.sort(by:)`
This method sorts or rearrange the values inside the array according to a condition.

For example here we can sort them from smaller to higher.

```swift
var numbers = [10, 24, 3, 73, 5]
numbers.sort(by: { $0 < $1 })
print(numbers) 
// Output: [3, 5, 10, 24, 73]
```

####`.first`
This property returns the first element of our array.

```swift
var numbers = [3, 63, 27]
print(numbers.first) 
// Output: 3
```

####`.last`
This property returns the last element of the array.

```swift
var numbers = [3, 63, 27]
print(numbers.last) 
// Output: 27
```
####`.removeFirst()`
This method removes the first element of the array.

```swift
var groceryList = ["Onions", "Apples", "Pasta"]
groceryList.removeFirst()
print(groceryList) 
// Output: ["Apples", "Pasta"]
```
####`.removeLast()`
This method removes the last element of the array.

```swift
var groceryList = ["Onions", "Apples", "Pasta"]
groceryList.removeLast()
print(groceryList) 
// Output: ["Onions", "Apples"]
```

####`.firstIndex(where:)`
This method returns the index of the first value that satisfies a condition.

```swift
var numbers = [3, 63, 27]
let firstIndex = numbers.firstIndex(where: { $0 > 10 })
print(firstIndex!) // Output: 1
```
####`.shuffled()`
This method returns a new array with the elements shuffled.

```swift
var numbers = [3, 63, 27]
let shuffled = numbers.shuffled()
print(shuffled) 
// Output: [27, 3, 63] (order will vary)
```
####`.reverse()`
This method reverses the order of the elements in the array.
```swift
var groceryList = ["Onions", "Apples", "Pasta"]
groceryList.reverse()
print(groceryList) 
// Output: ["Pasta", "Apples", "Onions"]
```

####`.allSatisfy(_:)`
This method returns true if **all** elements satisfy a condition, otherwise false.

```swift
var numbers = [3, 63, 27]
let allGreaterThanTen = numbers.allSatisfy { $0 > 10 }
print(allGreaterThanTen) // Output: false
```
####`.contains(_:)`
This method checks if the array contains a specific element.

```swift
var numbers = [3, 63, 27]
let containsTwentySeven = numbers.contains(27)
print(containsTwentySeven) 
// Output: true
```
####`.isEmpty`
This property checks if the array is empty and returns a boolean result.

```swift
var numbers = [3, 63, 27]
print(numbers.isEmpty) // Output: false
```

___

###Resources

If you want a Cheat Sheet with some of this methods and properties, feel free to save or download this image. If you share it please do not delete or hide my name 🫶🏻​

![Cheat sheet with some of the methods and properties of arrays](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a1026redo3m4v4pwbthq.png)

Also if you want to keep learning more about this I highly recommend checking the official documentation and courses [here](https://developer.apple.com/learn/)

___
###Want to keep learning about Swift? 
This a full series on [Swift 101](https://dev.to/silviaespanagil/swift-101-getting-into-ios-development-gji), next chapter will be the second part of Collections where I will share about Sets, Tuples and Dictionaries, so I hope to see you there!

If you enjoyed this, please share, like, and comment. I hope this can be useful to someone and that it will inspire more people to learn and code with Swift