Swift – Reduce method

I was fiddling around with the swift reduce method and came across some findings of how it works.

The reduce method is actually part of a functional programming concept called list folding. The list folding has many variations such as reduce, fold, inject and so on. This generally depends on the functional language that we use.

The folding methods operate on Collections such as Arrays, Lists, Ranges. The main purpose of the folding methods are to combine elements in the collections and produce a result.  Examples of such operations could be sum all elements in a given array, multiply only odd elements in a given array of integers and so on. The most important feature of any fold operation is that they are immutable i.e they do not change the values of the collection on which they operate.

Over here we discuss about the swift variation of list folding reduce. A very common thing about every folding method is that they have an inbuilt accumulator. An accumulator is like a rough book or a white board which is used by the folding methods to store the intermediate value that is obtained by applying the combining operation.

For Eg: Suppose we want to add all the values of a list [1, 2, 4, 5, 6]
So the operation would be performed in such a way:

Operation      : +
List                  :       1   2   4   5   6
Accumulator : 0    1   3   7   12  18

An accumulator can be set an initial value or can have a default value. The reduce method allows us to set an initial value.

To explain the usage of reduce, I shall try to solve the above problem in 3 different versions. The first being a typical way by iterating, then replacing it with the reduce method and finally adding some syntactic sugar provided by swift. Please note that I am using XCode Playground to write the code.

The first way to solve this problem is:

let numbers = [1, 2, 4, 5, 6]
var sum = 0
for number in numbers {
sum += number
}
println(sum)

Let us look at a more functional way of solving this problem in swift and that is using the reduce method. In reduce method the inbuilt accumulator substitutes the work carried out by the sum variable used in above solution. So our new solution looks as follows:

var result = [1, 2,4,5,6].reduce(0, combine: {accumulator, value in
                                                               accumulator + value
})
println(result)

Let us try to understand what we are doing over here:
1.  The first parameter of  reduce method is the initial value of the accumulator.
2. The second parameter combine: takes a closure of type (U, T) -> U i.e a closure that takes two parameters and returns a value. This returned value is stored as the new value of the accumulator. Here U is the type of accumulator and T is the type of element in the list. In our case the accumulator is of type Int and the value in the list is also of type Int, so the closure that we pass over here would be of type (Int, Int) -> Int
So when the operation inside closure is applied on each element the accumulator will contain the result of the previous operation and value will contain the current value in the list on which the operation is to be applied.
3. We do not specify the types of the closure parameters as they are inferred by swift.

Now, in swift, if the last parameter of a method is a closure, then we can separate it out as follows:

var result = [1, 2,4,5,6].reduce(0) {accumulator, value in
                                              accumulator + value
})
println(result)

Swift allows us to make this operation more concise. We can actually replace the closure parameters with their positions i.e $0 and $1, where $0 points to accumulator parameter and $1 points to value parameter. So the solution now becomes:

var result = [1,2,4,5,6].reduce(0) {$0 + $1}
println(result)

Now as generating a sum of all elements in a list is a very common operation, Swift provides us with a + operation. So this expression can be rewritten as:

var result = [1,2,4,5,6].reduce(0, +)
println(result)

As we can see, the initial 6 lines of code had been reduced to mere two  lines.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s