I have a similar problem but I'd like to to sum up two fields instead of one (profit in the above example). let me explain:-
Here I'm defining the my array
struct DailyContractorsSummary : Identifiable, Hashable
{
var id = UUID()
var rigOperator: String
var lostTime: Int
var oPTime: Int
var efficiency: Double
var animate: Bool = false
}
I use the following to sum up oPTime
let filteredDailyContractorsSummary = Dictionary(grouping: Variables.dailyContractorsSummary) { element in
element.rigOperator
}.mapValues { recordsGroupedByRigOperator -> Int in
recordsGroupedByRigOperator
.map { ($0.oPTime) }
.reduce(0, +)
}.map { dailySummary in
FilteredDailyContractorsOPTime(rigOperator: dailySummary.key, oPTime: dailySummary.value, efficiency: 0)
}
I want to be able to sum up oPTime and lostTime. I can only successfully do it with oPTime or lostTime but not both together. Can you please help me? Thanks in advance
I want to be able to sum up oPTime and lostTime. I can only successfully do it with oPTime or lostTime but not both together. Can you please help me? Thanks in advance
The mapValues
closure can return a tuple (Int, Int)
. The first element is the sum of opTime
and the second element is the sum of lostTime
.
let filteredDailyContractorsSummary = Dictionary(
grouping: dailyContractorsSummary, by: \.rigOperator
)
.mapValues { recordsGroupedByRigOperator -> (Int, Int) in
recordsGroupedByRigOperator
.map { ($0.oPTime, $0.lostTime) }
.reduce((0, 0)) { ($0.0 + $1.0, $0.1 + $1.1) }
}
The expression ($0.0 + $1.0, $0.1 + $1.1)
is quite hard to read, but all its doing is adding two tuples ($0
and $1
) together, element by element.
It might help to write a function like this:
func +(lhs: (Int, Int), rhs: (Int, Int)) -> (Int, Int) {
(lhs.0 + rhs.0, lhs.1 + rhs.1)
}
Note that you can generalise this to any tuple arity and type, but this crashes the compiler in 5.10. It works in Swift 6 though.
func +<each T: AdditiveArithmetic>(lhs: (repeat each T), rhs: (repeat each T)) -> (repeat each T) {
(repeat ((each lhs) + (each rhs)))
}
Then you can write .reduce((0, 0), +)
.
It seems like you want to map the groups back to an array of DailyContractorsSummary
s, so you can add this at the end:
.map { key, value in
DailyContractorsSummary(rigOperator: key, lostTime: value.0, oPTime: value.1, efficiency: 0)
}