kurtixl
kurtixl

Reputation: 419

Javascript - calculations in a for loop

I'm not entirely sure if a for loop is the right thought the process to handle what my issue is. I am creating a line graph to display the % growth between two years for 10 years. I am able to get the data showing on the graph as expect but I unable to think of another way to make it more efficient. My current code works but I would like to handle the calculations for the entire array of data together rather than handling it separately.

my current logic:

const numerator is the index of the year I would to display a percentage growth I am subtracting it from const denominator

I am removing the commas in the first two lines since the value are higher numbers such as 1,323,349

Finally, the third line perChange is the calculation for the actual percentage. I am using 2 indexes at a time and using the larger number of the two to subtract the smaller one for example. index 1 - index 0; index 3 - index 2, index 5 - index 4 etc...

This is my current code:

const numeratorOne = Number(caArray[1].DataValue.replace(/,/g, ''))
    const denominatorOne = Number(caArray[0].DataValue.replace(/,/g, ''))
    const perChangeOne = 100 * Math.abs((denominatorOne - numeratorOne) / ((denominatorOne + numeratorOne ) /2 ) )

    const numeratorTwo = Number(caArray[3].DataValue.replace(/,/g, ''))
    const denominatorTwo = Number(caArray[2].DataValue.replace(/,/g, ''))
    const perChangeTwo = 100 * Math.abs((denominatorTwo - numeratorTwo) / ((denominatorTwo + numeratorTwo) / 2))

    const numeratorThree = Number(caArray[5].DataValue.replace(/,/g, ''))
    const denominatorThree = Number(caArray[4].DataValue.replace(/,/g, ''))
    const perChangeThree = 100 * Math.abs((denominatorThree - numeratorThree) / ((denominatorThree + numeratorThree) / 2))

    const numeratorFour = Number(caArray[7].DataValue.replace(/,/g, ''))
    const denominatorFour = Number(caArray[8].DataValue.replace(/,/g, ''))
    const perChangeFour = 100 * Math.abs((denominatorFour - numeratorFour) / ((denominatorFour + numeratorFour) / 2))

    const numeratorFive = Number(caArray[9].DataValue.replace(/,/g, ''))
    const denominatorFive = Number(caArray[8].DataValue.replace(/,/g, ''))
    const perChangeFive = 100 * Math.abs((denominatorFive - numeratorFive) / ((denominatorFive + numeratorFive) / 2))

    const numeratorSix = Number(caArray[11].DataValue.replace(/,/g, ''))
    const denominatorSix = Number(caArray[10].DataValue.replace(/,/g, ''))
    const perChangeSix = 100 * Math.abs((denominatorSix - numeratorSix) / ((denominatorSix + numeratorSix) / 2))

    const numeratorSeven = Number(caArray[13].DataValue.replace(/,/g, ''))
    const denominatorSeven = Number(caArray[12].DataValue.replace(/,/g, ''))
    const perChangeSeven = 100 * Math.abs((denominatorSeven - numeratorSeven) / ((denominatorSeven + numeratorSeven) / 2))

    const numeratorEight = Number(caArray[15].DataValue.replace(/,/g, ''))
    const denominatorEight = Number(caArray[16].DataValue.replace(/,/g, ''))
    const perChangeEight = 100 * Math.abs((denominatorEight - numeratorEight) / ((denominatorEight + numeratorEight) / 2))

    const numeratorNine = Number(caArray[17].DataValue.replace(/,/g, ''))
    const denominatorNine = Number(caArray[16].DataValue.replace(/,/g, ''))
    const perChangeNine = 100 * Math.abs((denominatorNine - numeratorNine) / ((denominatorNine + numeratorNine) / 2))


Highcharts.chart('container', {
    chart: {
        type: 'line'
    },
    title: {
        text: 'Gross State Product in California'
    },
    xAxis: {
        categories: ['1998', '2000', '2002', '2004', '2006', '2008', '2010', '2012', '2014', '2016', '2018'],
        title: {
            text: 'Year'
        },
    },

    yAxis: {
        categories: ['2', '4', '6', '8', '10'],
        title: {
            text: 'Percentage Change (%)'

        }
    },
    plotOptions: {
        line: {
            dataLabels: {
                enabled: false
            },
            enableMouseTracking: false
        }
    },
    series: [{
        name: 'California',
        data: [perChangeOne, perChangeTwo, perChangeThree, perChangeFour, perChangeFive, perChangeSix, perChangeSeven, perChangeEight, perChangeNine, 8.3, 3.9],
        color: '#002F65'

    }, {
        name: 'US',
        color: '#0B7070',
        data: [3.9, 4.2, 5.7, 8.5, 1.9, 5.2, 7.0, 6.6, 4.2, 5.3, 10]
    }]
});
}

The desired outcome is a way to get the same results without having to create 10 different variables as I will need to continue to add more data to this graph in the future.

I have attempted this:

for (let i = 0; i < caArray.length; i++) { 
 let removeComma = Number(caArray.DataValue.replace(/,/g, ''))
}

for (let i = 0; i < removeComma.length; i += 2) { 
// math logic here which I do not know how to work out
}

Upvotes: 1

Views: 124

Answers (2)

Diogo Aleixo
Diogo Aleixo

Reputation: 871

If i understood correctly you just need one loop. You need to iterate by two each and then you have all the data in your current iteration. Something like this.

const changes = []

for(let i = 0; i < caArray.length; i+=2) {
  if (!caArray[i + 1]) {
      break
  }

  const denominator = Number(caArray[i].DataValue.replace(/,/g, ''));
  const numerator = Number(caArray[i + 1].DataValue.replace(/,/g, ''));
  const perChange = 100 * Math.abs((denominator - numerator) / ((denominator + numerator ) /2 ) )
  changes.push(perChange);
}

This should work.

Upvotes: 0

CertainPerformance
CertainPerformance

Reputation: 371203

Iterate over the caArray first, pushing to either a numerators or denominators array, depending on the index of the item you're iterating over. Then map the numerators array to get the associated denominator and calculate the change, and you'll have the array you can put into the series.data property:

const numerators = [];
const denominators = [];
caArray.forEach(({ DataValue }, i) => {
  const arrToPushTo = i % 2 === 0 ? denominators : numerators;
  arrToPushTo.push(Number(DataValue.replace(/,/g, '')));
});
const changes = numerators.map((numerator, i) => {
  const denominator = denominators[i];
  return 100 * Math.abs((denominator - numerator) / ((denominator + numerator) / 2));
});
series: [{
  name: 'California',
  data: [...changes, 8.3, 3.9],

const caArray = [
  { DataValue: '10' },
  { DataValue: '20' },
  { DataValue: '30' },
  { DataValue: '40' },
];

const numerators = [];
const denominators = [];
caArray.forEach(({ DataValue }, i) => {
  const arrToPushTo = i % 2 === 0 ? denominators : numerators;
  arrToPushTo.push(Number(DataValue.replace(/,/g, '')));
});
const changes = numerators.map((numerator, i) => {
  const denominator = denominators[i];
  return 100 * Math.abs((denominator - numerator) / ((denominator + numerator) / 2));
});

console.log(changes);

Upvotes: 1

Related Questions