The Power of Reduce
Published on Dec 3, 2019The Power of Reduce — SwiftMoji Entry #3
In Swift, higher-order functions (functions which take another function as an argument) can drastically improve readability and shrink code size. In the following example, the reduce(into:_:) method on Array is used to combine elements into a Dictionary which maps each unique element to its corresponding count. More specifically, an Array of animal emojis is converted into a Dictionary by mapping each animal to its count. The initialResult of this operation is just an empty Dictionary ([:]). The animalCounts parameter in the closure is inferred to be of the type [String: Int] based on the surrounding context. Additionally, animalCounts is marked as inout because it is mutated in the closure. Next, the Dictionary of animal counts is converted into an Array of Strings describing the number of scientific groupings commonly formed. The initialResult of this reduce is an empty Array ([]). In each iteration of the reduce, a new key-value pair from the Dictionary of animalCounts is generated. The key is then used to look-up the correct AnimalGroup classification which provides the details necessary to calculate the number of groups present.
import Foundation
typealias AnimalGroup = (name: String, size: Int)
let animalGroups: [String: AnimalGroup] = [
"🐬": ("pod", 12),
"🐺": ("pack", 6),
"🦒": ("tower", 10)
]
let animals = [
"🐬", "🐬", "🐬", "🐬", "🐬", "🐬",
"🐬", "🐬", "🐬", "🐬", "🐬", "🐬",
"🐺", "🐺", "🐺", "🐺", "🐺", "🐺",
"🐺", "🐺", "🐺", "🐺", "🐺", "🐺",
"🦒", "🦒", "🦒", "🦒", "🦒", "🦒",
"🦒", "🦒", "🦒", "🦒"
]
let groupedAnimals = animals
.reduce(into: [:]) { animalCounts, animal in
animalCounts[animal, default: 0] += 1
}
.reduce(into: []) { groups, animalCount in
let animal = animalCount.key
let amount = animalCount.value
let groupSize = animalGroups[animal]!.size
let groupName = animalGroups[animal]!.name
let amountOfGroups = Int((Double(amount) / Double(groupSize)).rounded())
groups.append("\(amountOfGroups) \(groupName)\(amountOfGroups > 1 ? "s" : "") of \(animal)")
}
// ["2 packs of 🐺", "1 tower of 🦒", "1 pod of 🐬"]
Tagged with: