I'm currently working on a project that involves distributing the values of an array in a way that the total sum equals 100.
Here are some examples:
[70, 34, 92]
with a total value of100
. The output is[35.71, 17.35, 46.94]
because35.71 + 17.35 + 46.94 = 100
.[86, 99.5, 100]
with a total value of100
. The output is[30.12, 34.85, 35.03]
.[96, 37]
with a total value of100
. The output is[72.18, 27.82]
.[98, 76.5, 68.5, 63.5, 38.5]
with a total value of100
. The output is
which equals 100 when summed up.[28.41, 22.17, 19.86, 18.41, 11.15]
My current approach is as follows:
- Add all the values in the given array
- Multiply each value by 100
- Divide each value by the total sum
- Use
.toFixed(2)
.
The calculation formula used:
+(((valueOfArray * 100) / totalSumOfGivenArray).toFixed(2))
However, my initial solution sometimes falls short of returning exactly 100 due to decimal issues like 99.99, 99.999999, 100(mostly), 100.0000000001, 99.999978, 100.09999999, 99.000009. This has led me to consider other approaches.
Another method I explored goes as follows:
let i = 0;
for(i = 0; i < controlsKey.length-1; i++){
let formId = controlsKey[i];
relValue = this.getDistributedValue(+form.controls[formId].value, totalActualSum); // returns formula result
form.controls[formId].setValue(relValue))
relativeSum = relativeSum + relValue;
}
relValue = 100 - relativeSum;
form.controls[controlsKey[i]].setValue(relValue)
This method works well too, but I am still seeking a more elegant solution for this problem.
The initial solution is acceptable to me, even though there are some lingering decimal issues despite using .toFixed(2)
.