th-hq
th-hq

Reputation: 57

Calculate quarterly values from an array of values

I have a javascript array of 12 values, each number represents a month. The array is already sorted by months ( format ['Jan', 'Feb', 'Mar', …, 'Dec'] ):

var revenue = [207485.19, 273455.34, 343804.25, 290400.2, 330941.67, 225798.4, 295580.96, 189529.26, 258365.37, 240740.14, 202847.97, 0]

The goal is to dynamically sum all the number by quarters and get the following output:

var revenue = [824744.78, 847140.27, 743475.59, 576379.85]

Below is what I started doing, but got stuck inside the if statements

const result = revenue.reduce((a, b, i) => {
 var initialQuarterIndex  = 0;
 var quarterIndex = Math.floor(i/3);
 if(quarterIndex === initialQuarterIndex ) {
   // do something here
 } else {
   // do something here
 }
}

Upvotes: 0

Views: 733

Answers (5)

Addis
Addis

Reputation: 2530

You may also do it with a for loop:

var revenue = [207485.19, 273455.34, 343804.25, 290400.2, 330941.67, 225798.4, 295580.96, 189529.26, 258365.37, 240740.14, 202847.97, 0]

var result = []; 
let sum = 0;

for( let i=0; i<revenue.length; i++) {
  sum += revenue[i];
  if( (i+1) % 3 === 0 ) {
    result.push(sum);
    sum = 0;
  }
}

console.log(result)

Upvotes: 1

Saurabh Agrawal
Saurabh Agrawal

Reputation: 7739

You can splice array into quarters and then calculate sum of each quarter using reduce()

Try this:

let revenue = [207485.19, 273455.34, 343804.25, 290400.2, 330941.67, 225798.4, 295580.96, 189529.26, 258365.37, 240740.14, 202847.97, 0];
let res = [];
for (let i = 0; i <= 3; i++) {
  let quarter = revenue.splice(0, 3);//splice in quarters
  let sum = quarter.reduce((v1, v2) => {
    return v1 + v2;
  })//calculate sum
  res.push(sum);
}
console.log(res);

Upvotes: 1

arizafar
arizafar

Reputation: 3122

You can use Array.reduce to loop through and use Math.floor(i/3) to split the quarter data.

var revenue = [207485.19, 273455.34, 343804.25, 290400.2, 330941.67, 225798.4, 295580.96, 189529.26, 258365.37, 240740.14, 202847.97, 0];

let out = revenue.reduce((acc, curr, i) => {
	let index = Math.floor(i/3)
	acc[index] = acc[index] + curr;
	return acc
}, Array(4).fill(0));

console.log(out)

OR one-liner solution

let out = revenue.reduce((acc, curr, i) => (acc[Math.floor(i/3)] +=  curr, acc), Array(4).fill(0));

Upvotes: 1

kockburn
kockburn

Reputation: 17616

You can accomplish this with Array#reduce, Array#fill, Array#map

  1. Create an empty array with a length equal to 4 (quarters)
  2. Fill the array with undefined (otherwise .map won't work)
  3. .map through your array and generate the indexes to calculate each quarter ( = 3, 6, 9, 12)
  4. .map through the generated indexes and calculate the sum of the slices ( = 0 to 2, 3 to 5, 6 to 8, 9 to 11 )

var revenue = [207485.19, 273455.34, 343804.25, 290400.2, 330941.67, 225798.4, 295580.96, 189529.26, 258365.37, 240740.14, 202847.97, 0];

const sum = (a) => a.reduce((acc, cur)=>acc + cur);

const groupsOf = 4;

const res = (new Array(groupsOf))
.fill(undefined)
.map((_, i) => (i+1) * revenue.length / groupsOf)
.map((offset, i, arr) => sum(revenue.slice(arr[i-1] || 0, offset)));

console.log(res);

Upvotes: 0

Nick Parsons
Nick Parsons

Reputation: 50814

You can use .reduce() and only add to the current value if you're on a current quarter, if you're on a new quarter (i % 3 === 0) then you can add the current value as a new quarter (ie new element) which will then be added to later:

const revenue = [207485.19, 273455.34, 343804.25, 290400.2, 330941.67, 225798.4, 295580.96, 189529.26, 258365.37, 240740.14, 202847.97, 0];

const res = revenue.reduce((acc, n, i) => {
  const curr = acc.pop();
  return i && i % 3 === 0 ? [...acc, curr, n] : [...acc, curr+n]
}, [0]);

console.log(res);

Upvotes: 1

Related Questions