i have an array of objects like this:
i/p:
let payments=[ {from:"b",to:"c",amount:30}, {from:"a",to:"c",amount:30}, {from:"c",to:"a",amount:50}, {from:"b",to:"a",amount:50}, {from:"c",to:"b",amount:66.66}, {from:"a",to:"b",amount:66.66}, {from:"a",to:"c",amount:150}, {from:"b",to:"c",amount:150}, {from:"a", to:"c",amount:75}, {from:"b", to:"c",amount:125} ]
now i want to perform sum operation on amount property, based on same property values, and minus operation on amount property based to reverse matching property values(i,e from,to), reduce the array to :
o/p:
[ { from: "b", to: "c", amount: 238.34 }, //(sum of all b->c amounts) minus (sum of all c->b amounts) { from: "a", to: "c", amount: 205 }, //(sum of all a->c amounts) minus (sum of all c-a amounts) { from: "a", to: "b", amount: 16.66 }, //(sum of all a->b amounts) minus (sum of all b->a amounts) ];
note: resultant array amount property shouldn’t be negative
i have tried few of the methods, but cant able to achieve this.
Advertisement
Answer
Maybe this will be helpful:
let payments=[ {from:"b",to:"c",amount:30}, {from:"a",to:"c",amount:30}, {from:"c",to:"a",amount:50}, {from:"b",to:"a",amount:50}, {from:"c",to:"b",amount:66.66}, {from:"a",to:"b",amount:66.66}, {from:"a",to:"c",amount:150}, {from:"b",to:"c",amount:150}, {from:"a", to:"c",amount:75}, {from:"b", to:"c",amount:125} ]; let pay = Object.entries( payments.reduce((tot,{from,to,amount})=>{ let u=from+'-'+to; // from-to-relationship (in alphabetical order) if (to<from) { u=to+'-'+from; amount=-amount } tot[u]=(tot[u]||0)+amount; // collate all payments here return tot; }, {}) ).map(([u,a])=>{let ft=u.split('-'); if (a<0) {ft=ft.reverse();a=-a} return {from:ft[0], to:ft[1], amount:a.toFixed(2)} }) console.log(pay)
In the .reduce
function I collate all payments between two partners into an accounts object with “acounts” named after “from-to” this name is always established in alphabetical order, so, if I encounter a payment {from:"b", to:"a", amount:123}
I swap the order and make the amount negative:
if (to<from) { u=to+'-'+from; amount=-amount }
After having done this I walk through the accounts object with Object.entries
. This will allow me to separate the account names into from
and to
partners again. This time I check, whether the amount payable between the partners would be negative. If so I swap the order of the partners (ft
) and multiply the amonut (a
) by -1:
if (a<0) {ft=ft.reverse();a=-a}