Home > Blockchain >  How to sum data by date filter in Javascript?
How to sum data by date filter in Javascript?

Time:02-11

I try to find a solution to sum cost data (to group thme by day) with ISO date information in object.

My data object looks like :

0: {id: 45, title: 'abo', cost: 10, recurrent: true, date: '2022-02-09T20:43:30.139Z'}
1: {id: 123, title: 'test 4', cost: 20, recurrent: false, date: '2022-02-09T20:43:30.139Z'}
2: {id: 125, title: 'test 3', cost: 50, recurrent: false, date: '2022-02-06T23:00:00.000Z'}
3: {id: 125, title: 'test 2', cost: 100, recurrent: false, date: '2022-02-05T10:00:00.000Z'}
4: {id: 125, title: 'test 1', cost: 122, recurrent: false, date: '2022-02-04T23:00:00.000Z'}

The expected result : sumData = [222,50,30]

  • Total cost for the 2022-02-05 = 222
  • Total cost for the 2022-02-06 = 50
  • Total cost for the 2022-02-09 = 30

I try to sum with something like that :

    let currentDate     = '';
    let currentTotal    = 0;
    let sumData         = [];

    if(data) {
        for (let index = 0; index < data.length; index  ) {
             
            //init date to compare with
            if(currentDate === '') {
                currentDate = new Date(data[index].date);
                currentTotal = data[index].cost;
            }
            else {
                const nextDate =  new Date(data[index].date);
                //test if is same day, sum expenses and add in sumData array
                if(currentDate.getFullYear() === nextDate.getFullYear() &&
                currentDate.getMonth() === nextDate.getMonth() &&
                currentDate.getDate() === nextDate.getDate()) 
                {
                    console.log('DATE = '   currentDate.getDate());
                    console.log(data[index].date);
                    console.log('COST = '   data[index].cost);
                    console.log('currentTotal = '   currentTotal);
                    currentTotal = currentTotal   data[index].cost;
                    console.log(index   ' - COST = '   data[index].cost);
                    console.log('TOTAL = '   currentTotal);
                    console.log('==========='); 
                }
                else {
                    //push last valid sum before reset
                    currentTotal = 0;
                    //reset sum with last data
                    currentTotal = data[index].cost;
                }
                currentDate =  new Date(data[index].date);
            }   
        }
    }
    console.log('== SUM data ==');
    sumData.push(currentTotal);

CodePudding user response:

You can try to use .reduce() and Object.values() to achieve your goal:

const data = [
{id: 45, title: 'abo', cost: 10, recurrent: true, date: '2022-02-09T20:43:30.139Z'},
{id: 123, title: 'test 4', cost: 20, recurrent: false, date: '2022-02-09T20:43:30.139Z'},
{id: 125, title: 'test 3', cost: 50, recurrent: false, date: '2022-02-06T23:00:00.000Z'},
{id: 125, title: 'test 2', cost: 100, recurrent: false, date: '2022-02-05T10:00:00.000Z'},
{id: 125, title: 'test 1', cost: 122, recurrent: false, date: '2022-02-04T23:00:00.000Z'}
]

const res = Object.values(data.reduce((resMap, obj) => {
  const date = new Date(obj.date).toLocaleString().split(',')[0]
  if (resMap[date] !== undefined)
    resMap[date]  = obj.cost
  else
    resMap[date] = obj.cost

  return resMap;
}, {}))

console.log(res)

Update: use ISO8601 date

CodePudding user response:

You can do it this way.

Please note that I updated your last date, as it was 2022-02-04 instead of 2022-02-05 as it is told in your question.

var array = [
{id: 45, title: 'abo', cost: 10, recurrent: true, date: '2022-02-09T20:43:30.139Z'},
{id: 123, title: 'test 4', cost: 20, recurrent: false, date: '2022-02-09T20:43:30.139Z'},
{id: 125, title: 'test 3', cost: 50, recurrent: false, date: '2022-02-06T23:00:00.000Z'},
{id: 125, title: 'test 2', cost: 100, recurrent: false, date: '2022-02-05T10:00:00.000Z'},
{id: 125, title: 'test 1', cost: 122, recurrent: false, date: '2022-02-05T23:00:00.000Z'},
];

var result = [];

array.reduce(function(res, value) {
  let onlyDate = value.date.split('T')[0];
  
  // Second approach is just to take first 10 characters of a substring like this:
  // let onlyDate = value.date.substring(0, 10);
  
  if (!res[onlyDate]) {
    res[onlyDate] = { date: onlyDate, cost: 0 };
    result.push(res[onlyDate])
  }
  res[onlyDate].cost  = value.cost;
  return res;
}, {});

console.log("Result in format date/cost");
console.log(result);

const onlyCostsResult = result.map(item => item.cost);
console.log("Only costs");
console.log(onlyCostsResult);

  • Related