Reputation: 11175
I have a class which contains value change information - i.e. the amount and percentage that a particular thing has changed in value within a certain timeframe.
The class looks like this:
@objc internal final class ValueChange: NSObject {
// MARK: - Internal Properties
internal let timeframe: Timeframe
internal let value: NSDecimalNumber
internal let percentage: NSDecimalNumber
}
I need a way to calculate a weighted average of multiple of these objects. More specifically, I need a function which takes an array of ValueChange
s and adds the value properties together. The percentage properties should be averaged, while taking the value property into consideration (as a weighting).
For example, a weighted average of the following:
ValueChange(timeframe: .day, value: 10.0, percentage: 2.5)
ValueChange(timeframe: .day, value: 20.0, percentage: 5.0)
Would produce:
ValueChange(timeframe: .day, value: 30.0, percentage: 4.16666667)
I took a look at this answer, which suggests the zip function should be used. Unfortunately, I'm pretty unfamiliar with it at this point so I'm struggling to see how it would work with an array of objects rather than two arrays.
Any help would be much appreciated.
Upvotes: 2
Views: 57
Reputation: 1679
You can try this:
let arrays = [...] // Your ValueChange arrays
let weights:[Double] = arrays.map{ $0.value.doubleValue } // [10, 20]
let percentage:[Double] = arrays.map{ $0.percentage.doubleValue } // [2.5, 5.0]
let percentageResult = zip(percentage, weights).map { $0 * $1 }.reduce(0.0, +) / weights.reduce(0.0, +)
print("test: \(percentageResult)") // Print 4.1666666
zip function is to create an array of tuple from 2 arrays (here it create tuple array ([2.5, 5.0], [10, 20])
). So when you do $0 * $1
inside the map
function, it will result the array [2.5 * 10, 5.0 * 20]
.
Hope this helps.
Upvotes: 1