2

I'm trying to build my own app, and I'm stuck at one issue that I cannot solve. My app deals with mortgages. I have several mortgages running in parallel, and I just need to sum-up total payments per period.

Let's say that we have the following arrays of objects (i.e. mortgages):

[ {uptomonth:84 , payment:150} ] 
[ {uptomonth:120 , payment:200} ] 
[ {uptomonth:120 , payment:100} , {uptomonth:180 , payment:250} , {uptomonth:300 , payment:500} ] 

How to read this (example for 1st line): "up to month number 84, I pay $150 per month".

I want to combine arrays into one array (e.g. using array.concat...), then sort objects by "uptomonth" in order to obtain a result array like that:

[ {uptomonth:84,payment:1200} , {uptomonth:120,payment:1050} , {uptomonth:180,payment:750} , {uptomonth:300,payment:500} ] 

The most difficult for me is to group by "uptomonth" (since there are duplicates of this value), and get the total payments per "uptomonth"...

Any idea of how to do that? Thanks a lot!

nadir
  • 1,223
  • 4
  • 12
  • 21

3 Answers3

0

You can do this task like this:

  1. Flatten the array to array with objects only
  2. Sort that new array
  3. Calculate total payment
  4. Group by uptomonth and calculate payment for each one

var data = [[ {uptomonth:84 , payment:150} ],[ {uptomonth:120 , payment:200} ],[ {uptomonth:120 , payment:100} , {uptomonth:180 , payment:250} , {uptomonth:300 , payment:500} ] ];

var finalResult = [];

//Flatten the array
var newArray = data.reduce(function(r, a) {
  a.forEach(function(o) {r.push(o)});
  return r;
}, [])

//Sort the array
newArray.sort(function(a, b) {
  return a.uptomonth - b.uptomonth;
});

//Get total payment
var total = newArray.reduce(function(r, a) {
  return r = r + a.payment;
}, 0)

//Group by uptomonth and calculate payment for each one
newArray.forEach(function(o) {
  if (!this.payment) this.payment = total;
  if (!this[o.uptomonth]) {
    this[o.uptomonth] = {uptomonth: o.uptomonth, payment: this.payment}
    finalResult.push(this[o.uptomonth]);
  }
  this.payment -= o.payment;
}, {});

console.log(finalResult)
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
0

Try this

var data = [[ {uptomonth:84 , payment:150} ],[ {uptomonth:120 , payment:200} ],[ {uptomonth:120 , payment:100} , {uptomonth:180 , payment:250} , {uptomonth:300 , payment:500} ] ];

var newData = {};

data.forEach(function(array)
         { array.forEach(function(node)
                     {
                         if(!newData[node.uptomonth]){newData[node.uptomonth]=0};
                         newData[node.uptomonth] += node.payment;
                     });
         });

var ans = [];

Object.keys(newData).forEach(function(key){
    var abc = {};
    abc.uptomonth = key;
    abc.payment=newData[key];
    ans.push(abc);
});

ans.sort(function(a,b){return parseInt(a.uptomonth)>parseInt(b.uptomonth)});

the variable ans is your desired array.

0

I'd recommend you to use _.flatten method from lodash.

var data = [[ {uptomonth:84 , payment:150} ], 
            [ {uptomonth:120 , payment:200} ] ,
            [ {uptomonth:120 , payment:100} , 
              {uptomonth:180 , payment:250} , 
              {uptomonth:300 , payment:500} ]]

_
 .chain(data)
 .flatten()
 .reduce((acc, obj) => {
   var month = obj.uptomonth
   var payment = obj.payment

   if (acc[month]) acc[month] += payment
   else acc[month] = payment

   return acc
 }, {})
 .value()
uladzimir
  • 5,639
  • 6
  • 31
  • 50