Data Structures and Algorithms in Swift: Arrays

November 6, 2018 Md. Zahed Hossain

What are Data Structures?

Data structures are the basic building blocks used in a system. They allow you to develop efficient, scalable, and maintainable systems. They also provide a means of organizing and representing data needing to be shared across different entities. Data structures not only make sharing data easier, but also make it easy to persist, sort, and search.

All software applications are based on data regardless of the type of system that you are developing. Most modern application developments use Application Programming Interfaces (APIs) to help them create amazing new products; however, these APIs still make use of their data structures and algorithms.

There are two fundamental data structures that are crucial to any software development: Array and Linked List. These fundamental data structures are necessary to build more advanced data structures. In this article I will talk about Array.

What is an Array?

An Array is an ordered, random-access collection that is contiguous, meaning it stores data in adjoining sectors of memory. It is the most well-known data structure and is built into most programming languages. In mathematical notation, a one-dimensional Array is represented as follows:

Mathematical representation of a one-dimensional Array

Where a0 represents the first element of the Array and ai represents the (i+1)th element of the Array.

Another form of Array is the multi-dimensional Array. A multi-dimensional matrix is implemented as a multi-dimensional Array. The example below depicts a two-dimensional matrix, which is implemented as a two-dimensional Array.

Mathematical representation of a two-dimensional Array

a00 represents the element in the first row and first column. Similarly, aij represents the element in the (i+1)th row and (j+1)th column.

In Swift, there are three ways that you can declare and initialize an Array:

1. The full form that uses Array<ElementType> notation

2. The shorthand form that uses [ElementType] notation

3. Type inference

We can use the full form to declare an Array as follows:

var arrayOfInts: Array<Int> = [1, 2, 3, 4, 5, 6]

Here we declared and initialized an Array named arrayOfInts containing type Int where the first element of the Array is 1 and the last element is 6. We can use Array indexing to access each element of this Array. Remember that Array is zero-index based in Swift so the last element of the above Array is accessed by arrayOfInts[5].

To declare an Array using the shorthand notation, we write:

var arrayOfInts: [Int] = [1, 2, 3, 4, 5, 6]

Finally, to declare an Array using type inference, we write:

var arrayOfInts = [1, 2, 3, 4, 5, 6]

The way type inference works is the Swift compiler determines the type of the elements based on the value you provide at compile time.

In Swift, the shorthand notation is not only the preferred way of declaring an Array, but is also recommended by Apple. Type inference can work, but is risky as Swift sometimes fails to determine the correct type of the values. For example:

var arrayOfFloats = [1.1, 1.2, 1.3, 1.4]

Though the intention was to declare and initialize an Array of type Float, Swift’s type inference will initialize arrayOfFloats as an Array of type Double instead.

The other advantage of the shorthand form over type inference is that it makes code more readable. If you just declare an empty Array on top of the class, it is difficult to know what it is meant to store. Using the shorthand to declare and initialize an empty Array makes it very clear.

Retrieving elements from an Array

There are many ways to retrieve an element from an Array. If you want just one element and you know the index of that element, you can use the subscript notation:

let arrayOfInts: [Int] = [1, 2, 3, 4]
let secondElementOfArray = arrayOfInts[1]

The above notation will get you the value 2. If you want to iterate through all values in the Array, subscript notation isn’t enough. You will need to use the for…in syntax:

let arrayOfInts: [Int] = [1, 2, 3, 4]
for anInt in arrayOfInts {
    print(“Now printing: \(anInt)”)
}

The above code will print each element of the Array one by one until it has printed all of them.

You can also use the first and last properties of the Array class to get safe access to the first and last elements of the Array, respectively. These properties will return nil if the Array is empty. For example:

let arrayOfInts: [Int] = [1, 2, 3, 4]
let firstInt: Int? = arraysOfInts.first
let lastInt: Int? = arraysOfInts.last

The above two lines will return 1 and 4 respectively. Notice that the type of firstInt and lastInt is not Int. They are of type Optional, meaning they can either have a value of type Int or a value of type nil.

Adding elements to an Array

There are also many ways to add an element to an Array, depending on where you want to add the element. To add single elements to the end of the Array you can use the append(_:) method:

var arrayOfInts: [Int] = [1, 2, 3, 4, 5]
arrayOfInts.append(6)
// arrayOfInts === [1, 2, 3, 4, 5, 6]

To add multiple elements to an Array, you can pass another Array or sequence of any kind to the append(contentsOf: ) method. For example, suppose we define two Arrays like below:

var firstArray: [Int] = [1, 2, 3]
var secondArray: [Int] = [4, 5, 6]

Now, let’s see what happens in two different cases.

Case 1:

firstArray.append(contentsOf: secondArray)
// firstArray === [1, 2, 3, 4, 5, 6]

Case 2:

secondArray.append(contentsOf: firstArray)
// secondArray === [4, 5, 6, 1, 2, 3]

You can add single elements at any position of the Array by using the insert(_:at: ) method:

var arrayOfInts: [Int] = [1, 2, 3, 4, 5]
arrayOfInts.insert(6, at: 3)
// arrayOfInts === [1, 2, 3, 6, 4, 5]

Finally, to add multiple new elements in the middle of the Array you can use insert(contentsOf:at: ) method:

var firstArray: [Int] = [1, 2, 3]
var secondArray: [Int] = [4, 5, 6]
firstArray.insert(contentsOf: secondArray, at: 2)
// firstArray === [1, 2, 4, 5, 6, 3]

Removing elements from an Array

Similar to retrieving and adding, you can remove elements from an Array using several methods, depending on whether you want to remove an element at the end of an Array or remove an element anywhere between the beginning and end of an Array.

To remove the last element of an Array, you can use the removeLast() method:

var arrayOfInts: [Int] = [1, 2, 3, 4, 5]
arrayOfInts.removeLast()
// arrayOfInts === [1, 2, 3, 4]

To remove an element from anywhere in the Array, you can use the remove(at: ) method:

var arrayOfInts: [Int] = [1, 2, 3, 4, 5]
arrayOfInts.remove(at: 3)
// arrayOfInts === [1, 2, 3, 5]
arrayOfInts.remove(at: 0)
// arrayOfInts === [2, 3, 5]

To remove a range of elements from the Array you can use the removeSubrange(_: ) method:

var arrayOfInts: [Int] = [1, 2, 3, 4, 5, 6]
arrayOfInts.removeSubrange(1..<4)
// arrayOfInts === [1, 5, 6]

Finally, to remove all the elements from an Array you can use the removeAll() method.

Array in Objective C vs Swift

Arrays in Objective C and Swift are not the same. Swift Arrays are value type, meaning they are copied when passed around, whereas Objective C Arrays are reference type and are therefore not copied, but the reference to the object is passed around.

Another difference is that in Swift, there are no separate classes for mutable or immutable Arrays. Arrays are generic Structs<T>. To declare an Array as mutable or immutable we declare it with the var or let keyword, respectively. On the contrary, in Objective C, Array is implemented as a class so there are separate classes to indicate whether the Array is mutable or immutable. Hence, dealing with Arrays in Swift is a lot easier than Objective C.

Code is more readable in Swift and has fewer problems. Let’s look at an example of how to create Arrays in Objective C.

In Objective C, the NSArray class is used to create an immutable Array instance.

NSArray *stringArray = @[@“One”, @“Two”, @“Three”];

Here, we used the shorthand notation to create an immutable Array of type String containing three elements. To create a mutable copy of the same Array we have to instantiate an instance of NSMutableArray as follows:

NSMutableArray *mutableStringArray = @[@“One”, @“Two”, @“Three”];

To create a mutable array from an immutable array we use the mutableCopy method:

NSMutableArray *mutableFromImmutable = [stringArray mutableCopy];

On the other hand, since Arrays are value type in Swift, creating a mutable Array from an immutable one is as easy as assigning the immutable Array to a variable of type Array using var like below:

let immutableArray: [String] = [“One”, “Two”, “Three”]
var mutableArray: [String] = immutableArray

Since values are copied, the above statement copies the contents of immutableArray into mutableArray, which is mutable. This code looks much cleaner and more readable. This is one of the reasons why I like working with Swift Arrays more than that of Objective C.

Conclusion

We have gone through the basic functionalities of the Array data structure. This is the base knowledge for the upcoming parts of this multi-part blog series, where we will learn to implement more advanced data structures. If you want to learn more about the Array data structure check out Apple’s documentation. In the next part of this series, I will go through the second fundamental data structure: Linked List. Stay tuned!


Data Structures and Algorithms in Swift: Arrays was originally published in Achievers Tech on Medium, where people are continuing the conversation by highlighting and responding to this story.

No Previous Articles

Next Article
A Survival Guide: how to make it as a newly hired Software Engineer
A Survival Guide: how to make it as a newly hired Software Engineer

Congratulations, you are hired!You worked hard. You crushed your interview and whiteboarded like a pro. Tod...