Hallo mannen en vrouwen, Leo hier. Today’s topic is how to do Tuples to do Sorting Operations in Swift.

We will explore a lot of sorting possibilities using tuples. The sorting operation is pretty straightforward in Swift and can be used automatically with types that conform to comparable.

Sorting operations are very important to show data the way we want, so if the data isn’t in the right order we can easily fix that with the sorting operation. And even if the type doesn’t conform to the Comparable protocol, we can use a custom sorting closure to rearrange the data.

Fasten your seatbelts and prepare to code! But first…

 

Painting of The Day

A Trip to the Moon (French: Le Voyage dans la Lune) is a 1902 French adventure short film directed by Georges Méliès. This is a drawing by Georges Méliès of the vessel landing in the moon’s eye in the film “Le voyage dans la lune”. This film was inspired by a wide variety of sources, including Jules Verne’s 1865 novel From the Earth to the Moon and its 1870 sequel Around the Moon, the film follows a group of astronomers who travel to the Moon in a cannon-propelled capsule, explore the Moon’s surface, escape from an underground group of Selenites (lunar inhabitants), and return to Earth with a captive Selenite.

If you're a mid/senior iOS developer looking to improve your skills and salary level, join this 100% free online crash course. It's available only until April 28th, so click to get it now!

I choose this drawing because of the Movie struct example that I used. And this is a very very old movie (1902) with a drawing made by the director himself, pretty unusual, isn’t it?

 

The Problem – Using Tuples to do Sorting Operations in Swift

You want to sort a list of movies by the title, year, and director.

First of all, open your favorite Xcode’s Playground file and type this:

struct Movie {
    let title: String
    let year: Int
    let director: String
}

let movieList = [
    Movie(title: "Star Wars", year: 1898, director: "Leorge Mucas"),
    Movie(title: "A Star", year: 1922, director: "Michal Platpus"),
    Movie(title: "Be yourself", year: 1700, director: "Coey Vamn"),
    Movie(title: "The big bang", year: 2011, director: "Rom Natas"),
    Movie(title: "The big bang", year: 1922, director: "Adra Kngr"),
    Movie(title: "Finding Nemoy", year: 2022, director: "Raxip"),
    Movie(title: "The big bang", year: 2011, director: "Jos Klimbr")
]

Nothing fancy until now.

Now let’s sort the data based on the title ascending:

let sortedMovieList = movieList.sorted { // Mark 1
    $0.title < $1.title
}

for movie in sortedMovieList {
    print(movie)
}

The sorting function we are using is from Swift Array, it receives a closure with two parameters to know how it can compare two types (in this case two movies).

In Mark 1 we are taking advantage of trailing closures and implicitly parameters to compare two Strings and return a Boolean value that represents the comparison between the two movies:

summary of sorting in Swift image

You should see this result in the console:

first result of sorting example

Cool! That worked as we planned.

But what if we want the movie “The Big Bang” to be sorted with the year too?

 

Complex Sorting without Tuples

As you can see in the image above the title is sorted but the year is not. You can do this to fix:

let sortedMovieList = movieList.sorted {
    if $0.title == $1.title { // Mark 1
        return $0.year < $1.year // Mark 2
    }
    return $0.title < $1.title // Mark 3
}

for movie in sortedMovieList {
    print(movie)
}

This started to be a little confusing but it is still ok…

Mark 1 is saying: If the names are equal, please use another variable to compare. And Mark 2 is the other variable we use to compare, in this case, the year. The Mark 3 is used when the movie title aren’t equal so the comparison is just the title.

second result of sorting example

If you're a mid/senior iOS developer looking to improve your skills and salary level, join this 100% free online crash course. It's available only until April 28th, so click to get it now!

The result above demonstrates that our closure is working fine. All the films are sorted ascending by the title and films with equal names they are sorted by their year.

Let’s complicate a little more. In the image above you can see that films with the same name and the same year can have different directors( Hollywood can’t stop!), so it would be awesome to sort the director attribute in ascending order too. We can rearrange that too!

Let’s write some more code to accomplish this new feature:

let sortedMovieList = movieList.sorted {
    if $0.title == $1.title {
        if $0.year == $1.year {
            return $0.director < $1.director
        }
        return $0.year < $1.year
    }
    return $0.title < $1.title
}

for movie in sortedMovieList {
    print(movie)
}

Resulting in this:

third result of sorting example

The algorithm is the same and you can imagine if we had a big struct how confusing would be to maintain a code like this. This is starting to be a pyramid of doom so we have to do something.

Here is where the tuples save the day!

 

The Tuple Solution

Tuples comparisons are great to do what we want here. Just put every property that you want to compare inside the tuple and it’s done:

let sortedMovieList = movieList.sorted {
    ($0.title, $0.year, $0.director) < ($1.title, $1.year, $1.director)
}

for movie in sortedMovieList {
    print(movie)
}

This way you can sort your data by title, year, and finally director with ease of use syntax. Swift is awesome, isn’t it?

And another perk is that if you want to sort by the year, title and director, in this order you can just change the position inside the tuple:

let sortedMovieList = movieList.sorted {
    ($0.year, $0.title, $0.director) < ($1.year, $1.title, $1.director)
}

for movie in sortedMovieList {
    print(movie)
}

Resulting:

fourth result of sorting example

 

One Descending Element

You may be thinking: What if I wanted only the year to be descending, and the rest to be ascending?

Just change the $0 with the $1 parameter and you can achieve that.

Check the code below:

let sortedMovieList = movieList.sorted {
    ($0.title, $1.year, $0.director) < ($1.title, $0.year, $1.director)
}

for movie in sortedMovieList {
    print(movie)
}

Now the result is:

fifth result of Tuples to do Sorting Operations in Swift example

Check the movie “The Big Bang” now with the years in descending order instead of ascending, but the director is still ascending.

And… this is the end.

 

Continue Studying Algorithms

It is very important to know about recursion when dealing with tree data structures. This way you can study both topics, recursion, and trees, solving the problem of merging two binary trees in this article. There you will learn that you can merge any tree without having to create additional space to do it.

Want to discover the power of the Swift language and yet study algorithms? Well, you can find that and much more in the article about creating a linked list with Sequence and IteratorProtocol in Swift. There you will discover how to leverage your data structures with the native Swift language and make your types usable with “for each” keywords.

 

Summary – Tuples to Complex Sorting Operations in Swift

Today we learned how to use tuples to do complex sorting operations on types and why is important to know to simplify your code and make the maintenance easier for you and other in the future. Tuples are great in Swift and we should not underestimate their power.

That’s all my people, I hope you liked reading this article as much as I enjoyed writing it. If you want to support this blog you can Buy Me a Coffee or leave a comment saying hello. You can also sponsor posts and I’m open to freelance writing! You can reach me on LinkedIn or Twitter and send me an e-mail through the contact page.

Thanks for reading and… That’s all folks.

Credits:

title image