3 ms·
Can you post a (simplified) sketch of what your looping solution looks like? I'd like to give it a shot with map/filter/etc so we can compare.
by lodi 5y ago
Can you post a (simplified) sketch of what your looping solution looks like? I'd like to give it a shot with map/filter/etc so we can compare.
- magicalhippo 5y agoIt's very close to this, in C#-ish pseudocode, and barring errors introduced by my fried Friday brain. The duplicate invoice lookup isn't a linear search but I wanted to keep it simple. In reality order items have various sub-items, but lets ignore those. It's not super elegant, but in my mind it's straight forward and should be easy for my colleagues to jump in and understand. Though I'd be delighted to be proved wrong. var dstOrder = new Order(); var invoiceMap = new Dictionary<Invoice,Invoice>(); for srcOrder in SrcOrders do { for srcInvoice in srcOrder.Invoices do { // compares using invoice number and currency var dstInvoice = dstOrder.Invoices.Find(srcInvoice); if (dstInvoice == null) { dstInvoice = dstOrder.AppendInvoice(); dstInvoice.CopyFrom(srcInvoice); invoiceMap[srcInvoice] = dstInvoice; } else { dstInvoice.Amount += srcInvoice.Amount; } } for srcItem in srcOrder.Items do { var dstItem = dstOrder.AppendItem(); dstItem.CopyFrom(srcItem); // map old invoice reference to new (possibly consolidated) invoice dstItem.Invoice = invoiceMap[dstItem.Invoice]; } } dstOrder.Save(); return dstOrder;
- convolvatron 5y agosome of this is a little unclear. in particular how the source invoices are identified and mapped and therefore what invoiceMap really looks like. but here is a group/sum in a madeup datalog dialect: reconcile(dstId, amount) :- Orders(srcOrder) Invoices(srcInvoice, srcOrder) unique(dstId, srcInvoice.id) amount = { sourceInvoice.id = dstId, sum (srcInvoice.Amount) } that produces invoice/sum pairs. Orders and Invoices are your source relations. unique produces a set of unique source invoice ids, which drives the cardinality of the aggregate. the block notation is a scoping construct encapsulate the set cardinality changes. not going to claim that this is inherently more readable or captures all the subtleties. but you can imagine that terse expressions of intent like this are more accessible to the reader and less error prone. if not, I should do a better job.
- magicalhippo 5y agoSorry, I was in a bit of a hurry. An Invoice has essentially these fields: id InvoiceNo InvoiceDate Amount Currency The id is the unique id in the DB. For the purposes of consolidation we consider (InvoiceNo, Currency) as a tuple. For brevity I didn't include the failure mode of mismatching invoice dates, that can be checked in advance anyway so not terribly relevant. The invoiceMap maps instance to instance, or the unique id to unique id if you like.
- to11mtm 5y agoI guess my answer depends on what kind of DB this really is. If the app is running off a SQL Backend, you could probably do this with some well thought out queries, however whether doing so in an ORM/ActiveRecord Environment (which is what this looks like) will be beneficial might be another matter. For instance, if this was SQL and a Micro-ORM was involved, I'd instead try to grab all the data in one pass (With the right ones that's fairly simple,) Calculate my Insert set from that, and write out the new records. In that case though, there'd probably still be some form of LINQ/Looping, both on the level of business code, as well as under the wire. It would be more performant for sure, but to your point, IDK whether it would be more understandable