Het reduce mechanisme behoort tot de functionele operaties op datacollecties en is afkomstig uit functionele programmeertalen (map-reduce, fold). Historisch gezien stelt deze functie in staat om elke collectie om te zetten in een enkele geaggregeerde waarde (bijvoorbeeld, som, product, samenvoegen van strings, enz.), door alle elementen te doorlopen en het resultaat op te sparen. Het basisprobleem dat het oplost — beknopte, leesbare en foutvrije aggregatie van gegevens in plaats van handmatige lussen.
In Swift is reduce gedefinieerd als een methode van collecties:
func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, Element) throws -> Result) rethrows -> Result
Dit betekent dat je een beginwaarde opgeeft, en vervolgens een functie schrijft die voor elk element en de huidige accumulator een nieuwe geaggregeerde waarde teruggeeft.
Voorbeeldcode:
let numbers = [1, 2, 3, 4] let sum = numbers.reduce(0) { $0 + $1 } // 10 let joined = numbers.reduce("") { $0 + String($1) } // "1234"
Belangrijke kenmerken:
Hoe werkt reduce op een lege collectie?
Reduce wordt toegepast op elk element van de collectie. Als de collectie leeg is — wordt de initiële waarde geretourneerd, er zullen geen oproepen naar de closure zijn.
Voorbeeldcode:
let empty: [Int] = [] let sum = empty.reduce(100) { $0 + $1 } // 100
Kan je met reduce de originele collectie wijzigen?
Nee, reduce is een pure functie, het verandert de originele collectie niet. Alle wijzigingen gebeuren alleen met de accumulator.
Wat is het verschil tussen reduce en reduce(into:)?
reduce(into:) stelt in staat om de accumulator te muteren bij elke iteratie en werkt efficiënter met value-types, waar het maken van een nieuwe kopie (copy-on-write) kostbaar is.
Voorbeeldcode:
let nums = [1, 2, 3] let squares = nums.reduce(into: []) { (result: inout [Int], item) in result.append(item * item) } // squares == [1, 4, 9]
Een ontwikkelaar wilde de prijzen van producten in een array van products optellen. Hij gebruikte reduce met een initiële waarde van 0.0, maar de closure was zo ingericht dat deze soms een negatieve som terug gaf bij korting, wat leidde tot onjuiste totalen en problemen met de belastingberekening.
Voordelen:
Nadelen:
Reduce(into:) werd gebruikt om een cache op te bouwen uit een array van entiteiten op basis van id:
let objects: [Entity] = ... let cache = objects.reduce(into: [:]) { $0[$1.id] = $1 }
Voordelen:
Nadelen: