I am wanting to be able to sum multiple fields of a sequence. I don't know how to do this without iterating over the sequence multiple times. My perception is that this is inefficient. Is there a clever way to do this that I am not seeing?
type item = {
Name : string
DemandQty : decimal
Weight : decimal
UnitCost : decimal
}
let items =
{1..10}
|> Seq.map (fun x ->
{
Name = string x
DemandQty = decimal x
Weight = decimal x
UnitCost = decimal x
})
// This Works for a single value
let costSum =
items
|> Seq.sumBy (fun x -> x.DemandQty * x.UnitCost)
// This is similar to what I would like to do
let costSum, weightSum =
items
|> Seq.sumBy (fun x -> x.DemandQty * x.UnitCost, x.DemandQty * x.Weight)
Ideally I can sum multiple values that I am calculating by mapping over the sequence. Is my thinking off here?
I would also be interested in knowing what the performance impact is going to be if I have to iterate through the sequence multiple times to calculate all of the sums I am wanting. My perception is that this would be inefficient.
A straightforward way of summing is folding the sequence with a sum function:
let costSum, weightSum =
items
|> Seq.fold
(fun (costSum, weightSum) x -> (costSum + x.DemandQty * x.UnitCost, weightSum + x.DemandQty * x.Weight))
(0m, 0m)
As for the performance impact of iterating over the sequence multiple time is that it depends. The work of iterating over the sequence is repeated. So at the face of it is less efficient. However for shorter sequences when the number of repeated iterations is constant the performance impact might be negligible. Also computational complexity theory states that constants are ignorable when the number of elements increases.
In short, if it matters, benchmark on expected inputs. If it doesn't have a large enough impact go with the solution that offers best clarity.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With