F# Summing multiple fields in Seq<'T>
Asked Answered
C

1

5

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.

Campy answered 5/1, 2018 at 4:42 Comment(0)
U
6

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.

Ungodly answered 5/1, 2018 at 6:51 Comment(1)
This is fantastic. I knew there had to be some simple way!Campy

© 2022 - 2024 — McMap. All rights reserved.