Advanced Usage of Functional Methods

In the last post at reducing-code-for-readability-and-speed which took you through using functional methods instead of loops. The issue was that in some of these functions you might require the index and therefore pushed one back to using loops instead.

Let’s look at

Consider the code below, it iterates through the array and returns the array with every alternative value doubled.

let arrayNumbers = [15, 2, 6, 14, 3, 9]
var index = 0
var result:[Int] = []
for i in arrayNumbers {
    if index % 2 == 0 {
        result.append(i)
    } else {
        result.append(i * 2)
    }
}

now, if we simply wanted to double each value, then we could have used the map function as

let result = arrayNumbers.map { $0 * 2 }

However in this case, it would mean that we need an index to determine if the item is the next one or not.

What about other functions?

Let’s look at the same array and say we want to sum every other element, it would be quite easy if we wanted to sum all the elements by simply using

let result = arrayNumbers.reduce(0, +)

But back to the problem we are trying to resolve, sum every alternative number, that would put us to using

var index = 0
var total = 0
for i in arrayNumbers {
    if index % 2 == 0 {
        total += i
    }
}

Is there a better way?

Swift has a lot of functions and methods around collections, sequences, etc

for (index, value) in arrayNumbers.enumerated() {
    if index % 2 == 0 {
        print(value)
    }
}

this is similar to the for loop earlier but this time we also get the index for free if we use enumerated() which returns a Sequence with two elements, the offset and the element. The offset is what we are referring to as the index as in this case.

so we can now use our mapping function from the first paragraph, where we were attempting to double every other element in the array.

let results = arrayNumber.enumerated().map{(offset, element) -> Int in 
    if offset % 2 == 0 {
        return element * 2
    }
    return element
}

now, let us look at our other example where we were attempting to sum every other element

let total = arrayNumber.enumerated().reduce(0) {
    if $1.offset % 2 == 0 {
        return $0 + $1.element
    }
    return $0
}

So there we have it…

This is something that I was blissfully unaware of, did not play much with Sequences and Collections. However I had used it only with the for loops not with the functions, but the introduction to this opens many doors (so as to say). Have fun with this…

Views All Time
Views All Time
898
Views Today
Views Today
1
Posted in Article, Basics, Tip, Tutorial.