DEV Community

Thomas Garayua
Thomas Garayua

Posted on

Mastering the .reduce() Method in Swift

Not too long ago I had an interview with a high profile company. My interviewing anxiety had me like a deer in headlights, I was completely frozen. The interviewer wanted me to create a function that counts the holes within the characters of a string. The example the string "Hello, World" should return a value of 4 because "e", "o", "o" and "d". All these characters contains holes. I would like to go over how I solved the problem using .reduce().

Swift offers a ton of methods and functions to manipulate arrays, collections and other data. One of the most frequently used methods is .reduce(). I would like to go into the world of .reduce() by talking about its syntax, use cases, and practical examples to help you master the art of .reduce() in Swift!

.reduce()

At its core, .reduce() is a higher-order function that allows you to combine all the elements of an array into a single value. It iterates through each element of the array, performing an operation that combines the current element with an accumulating value. The result of this operation is then used as the accumulating value for the next iteration.

Here's the basic syntax of the .reduce() method:

let result = array.reduce(initialValue) { (accumulator, element) in
    // Combine accumulator and element to produce a new accumulator
}
Enter fullscreen mode Exit fullscreen mode
  • initialValue: This is the initial value of the accumulator. It sets the starting point for the reduction process.
  • { (accumulator, element) in ... }: This is a closure that defines the operation to be performed on each element. The accumulator is the result of the previous iteration, and element is the current element being processed.

Use Cases for .reduce()

1. Summing an Array of Numbers

One common use of .reduce() is to calculate the sum of an array of numbers. Here's how you can achieve this:

let numbers = [1, 2, 3, 4, 5]
let sum = numbers.reduce(0) { (accumulator, number) in
    return accumulator + number
}

print(sum) // Output: 15
Enter fullscreen mode Exit fullscreen mode

In this example, we start with an initial accumulator value of 0 and add each number from the array to it.

2. Finding the Maximum Value

You can also use .reduce() to find the maximum value in an array:

let numbers = [12, 4, 23, 6, 45]
let maxNumber = numbers.reduce(numbers[0]) { (accumulator, number) in
    return max(accumulator, number)
}

print(maxNumber) // Output: 45
Enter fullscreen mode Exit fullscreen mode

The max() function compares the current element with the accumulator and returns the greater of the two.

3. Concatenating Strings

.reduce() can be handy for concatenating strings together:

let words = ["Hello", " ", "World", "!"]
let sentence = words.reduce("") { (accumulator, word) in
    return accumulator + word
}

print(sentence) // Output: "Hello World!"
Enter fullscreen mode Exit fullscreen mode

Here, we start with an empty string as the initial accumulator and concatenate each word to it.

Handling Optional Results

Sometimes, you may want to perform a .reduce() operation on an array of optionals, and you need to handle the possibility of nil values. You can achieve this by providing an initial value that matches the type of the optional:

let numbers: [Int?] = [1, 2, nil, 4, 5]
let sum = numbers.reduce(0) { (accumulator, number) in
    return accumulator + (number ?? 0)
}

print(sum) // Output: 12
Enter fullscreen mode Exit fullscreen mode

In this case, we use the nil-coalescing operator (??) to handle the nil value by replacing it with 0.

Conclusion

The .reduce() method in Swift is a powerful tool for aggregating data in arrays, making it an indispensable feature for any Swift developer. Whether you need to calculate sums, find maximum values, or perform custom operations, understanding and mastering .reduce() is a key step in becoming proficient with Swift. So go ahead, leverage the versatility of .reduce() to simplify your code and make your Swift applications even more efficient and elegant.

Now with this information I want to challenge you to try the holeCounter algorithm using .reduce(). I'll give you a small hint, I created a dictionary using the characters as the key and the hole count as the values. If you're still having trouble I've provided the solution below. Good luck and happy coding!

Image description

Solution to holeCounter

func holeCounter(_ phrase: String) -> Int {
    let holeDict: [Character:Int] = [
        "A": 1, "B": 2, "D": 1, "O": 1, "P": 1, "Q": 1, "R": 1,
        "a": 1, "b": 1, "d": 1, e: 1, "g": 1, "o": 1, "p": 1, "q": 1
    ]

    return phrase.reduce(0) { count, char in
        count + (holeDict[char] ?? 0)
    }
}
Enter fullscreen mode Exit fullscreen mode

1. Dictionary Definition (holeDict)

A dictionary, holeDict, is defined to map certain characters to their corresponding hole count. For example, the character "A" has one hole, the character "B" has two holes, and so on.

2. Reduce Function

The reduce function is used to iterate over each character in the input string, phrase, and accumulate the total count of holes.

Top comments (2)

Collapse
 
jimmymcbride profile image
Jimmy McBride

Love this! The reduce method has saved me plenty of times before!

Collapse
 
ozxmin profile image
Osmin Vazquez Sanchez

Wasn't it more simple to use a Set instead of a Dictionary?