I am pretty new to functional programming and therefore F# and I have serious trouble to come up with the right solution for this problem.
I have got a sequence of record types, say like:
type Invoice = {
GrpText : string
GrpRef : int
Article : int
Wkz : int
Text : string
Price : decimal
InvoiceRef : int
}
Now I want to group or aggregate the sequence of Invoices by a given criteria and i.e. sum their prices. Invoices that does not match the criteria should not be grouped and just returned as they are.
A criteria function might look like this:
/// determines whether to group the two given Invoice items or not
let criteria item toCompareWith =
(item.GrpRef > 0 && item.Article = toCompareWith.Article
&& item.InvoiceRef = toCompareWith.InvoiceRef) ||
(item.Wkz <> 0 && item.Text = toCompareWith.Text)
The aggregation or grouping could look like this:
/// aggregate the given Invoice items
let combineInvoices item1 item2 =
{item1 with Price = item1.Price + item2.Price; Wkz = 0}
The problem looks kind of simple but I am currently not experienced enough in functional programming to connect the dots.
Edit:
I just modified the criteria function in order to better show that it might be a bit more complex than grouping by one or multiple fields.
Unless I’m missing something, there are two steps involved: group and reduce. The easiest way to group is
Seq.groupBy. Since you want to use custom equality you need to either apply the[<CustomEquality>]attribute to your type and overrideEqualsandGetHashCode, or roll your own key generating function that uses your concept of equality. Here’s an example of the latter.Usage