Swift Do Something Useful with Zip, Map, and Reduce

Keith Elliott (keithelliott.co)
Swift Programming
Published in
4 min readApr 29, 2016

Today’s article is the zip, map, and reduce functions in Swift. Let’s walkthrough a typical problem that you might come across in your coding endeavors.

Problem Statement

You work on a school grading app that allows teachers to monitor their students’ progress. You have information on each student in a class along with their grades for assignments and tests. All of this information is stored and can be retrieved in JSON, which means you can ultimately have structured arrays and dictionaries of data.

So far so good. However, your boss wants changes. She has asked you to give teachers more ways to analyze their students’ performance. While this work could be done on the server, she wants to see the functionality done in the client app to minimize network traffic along with a few other reasons for which she didn’t elaborate.

Disclaimer — this is a contrived example and we are going to simplify some of the assumptions to make the problem work with the lessons on zip, map, and reduce.

Let’s look at how we could begin to solve some of these challenges with zip, map, and reduce functions.

Zip

The zip method allows you to work with arrays, sets, dictionaries (or any type that conforms to the SequenceType protocol) to build a SequenceType from two underlying ones. Let’s break that down a bit.

A SequenceType is a protocol that allows a type to use a for…in loop. The built-in collection types are examples of SequenceType. Stepping one level down, the SequenceType protocol defines an associated type named Generator (as a GeneratorType) that is used to provide the iteration capability to get the next Element in the sequence. Putting all of this together, the zip method will create a sequence of pairs where the ith pair is composed of the index values at each of the underlying sequences. Let’s bring it home with an example.

Let’s say you have two arrays that you want to associate with each other. For example, you have an array of student names, and an array of grades that match those students index for index. How could I create a list with the student and grade combined at each index? You guessed it, we could use the zip method to combine them. See the code below.

Zip method — Combining two arrays into one array of tuples

Map

Each SequenceType has a map method that will iterate over its sequence and call a passed in transform function on each item — collecting and returning the results as a new array. Using the map function, you can convert an array of one type into an array of a different type. See the map method signature that follows:

func map<T>(@noescape _ transform: (Self.Generator.Element)->T) -> [T]

Constraints

Self : _CollectionWrapperType, Self.Index == Self.Base.Index

Extending our example from earlier, we can further format the result of our zip method output to include a letter grade and to convert the results to dictionaries that could be accessed via their keys.

Map method — Transforming an array of Tuples to an array of Dictionaries

Reduce

The reduce method returns a single result by repeatedly calling each item in the sequence and passing a combine function to accumulate values.

func reduce<T>(_ initial: T, @noescape combine combine: (T, Self.Generator.Element) ->T) -> T

The reduce method is extremely handy when you need to boil a collection of data points into a single value. As an example, it would be interesting to know how many A’s were awarded to our students. See below for an example.

Reduce method — Return the number of “A” grades

In the code above, we used the reduce method to start with an initial value of zero, and add 1 to our running total each time we find an “A” letter grade.

Final Thoughts

Hopefully, you can see how the zip, map, and reduce methods could be helpful in practice. Each of these methods has roots in functional programming and should lead to you writing cleaner code that is easier to understand and has few lines of code.

On a lighter note, I also wrote an article on why creating native apps is probably the best way to go in most of your mobile development endeavors. Please read that one and weigh in the discussion!

If you find this post helpful, please recommend it for others to read. You can visit me at www.gittielabs.com and subscribe to my RSS feed so that you won’t miss a post. I’m also putting together a video course to teach Swift development and could use your input on topics you feel would be helpful. Thanks for reading!

--

--

Keith Elliott (keithelliott.co)
Swift Programming

Tech vet, 20+ yrs from dev to CTO, startup enthusiast, husband, father of 5 + foster child. Eager to empower startups and motivate devs, thriving amid chaos.