javascript - 给定数组 "distribute/scale"的数量到特定值

标签 javascript arrays typescript decimal scale

我正在做一个项目,我需要分配一个数组的值,并且这些值的总和必须是 100。

例子:

  • [70, 34, 92] 和总值 100。输出为 [35.71, 17.35, 46.94] 因为 35.71 + 17.35 + 46.94 = 100
  • [86, 99.5, 100] 和总值 100。输出为 [30.12, 34.85, 35.03]
  • [96, 37] 和总值 100。输出为 [72.18, 27.82]
  • [98, 76.5, 68.5, 63.5, 38.5] 和总值 100。输出为 [28.41, 22.17, 19.86, 18.41, 11.15] = 100(sum)。

到目前为止我的解决方案:

  • 对给定数组中的所有值求和
  • 将每个值乘以 100
  • 将每个值除以总和
  • 使用 .toFixed(2)

“公式/计算”:+(((valueOfArray * 100)/totalSumOfGivenArray).toFixed(2))

我的第一个解决方案(小数问题所以 Not Acceptable ):

prioritySum  = 0;
controlsKey.forEach((value) => {
      priorityVal = this.getDistributedValue(+form.controls[formId].value, totalCatSum); // return +(((valueOfArray * 100) / totalSumOfGivenArray).toFixed(2))
      prioritySum = prioritySum + priorityVal;
});

此解决方案有时不会准确返回 100 值。输出各种如 99.99、99.999999、100(大部分)、100.0000000001、99.999978、100.09999999、99.000009。这里有一些十进制数的问题。

我使用的另一种方法是:

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)

这工作正常,但这个解决方案嗯...

所以我的问题是这个问题有什么优雅的解决方案吗?

第一个解决方案对我来说没问题,但即使我使用 .toFixed(2)

也存在一些小数问题

最佳答案

为了防止不需要的浮点值,您可以使用整数值并从 10000 的基值中减去该值(100 和两个位置)并创建一个字符串数组,其中点被插入获取格式化字符串的值。

const nice = s => s.toString().replace(/\d\d$/, '.$&');

function get100(array) {
    var sum = array.reduce((a, b) => a + b),
        offset = 1e4;
    return array.map((v, j, { length }) => {
        if (j + 1 === length) return nice(offset);
        var i = Math.round(v * 1e4 / sum);
        offset -= i;
        return nice(i);
    });
}

console.log(...get100([70, 34, 92])); // [35.71, 17.35, 46.94] 
console.log(...get100([86, 99.5, 100])); // [30.12, 34.85, 35.03].
console.log(...get100([96, 37])); // [72.18, 27.82].
console.log(...get100([98, 76.5, 68.5, 63.5, 38.5])); // [28.41, 22.17, 19.86, 18.41, 11.15]

关于javascript - 给定数组 "distribute/scale"的数量到特定值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58959464/

相关文章:

javascript - TinyMCE 'mceImage' execCommand 返回 false

javascript - 在图像 slider 中隐藏 View 之外的图像

javascript - 强制循环等待两个函数依次运行

C 编程 : Using function to return size of array

python - Python 新手 : Getting TypeError: unhashable type: 'list'

Javascript数组排序问题

javascript - 使用 ComponentDidUpdate 上的全局变量将状态从一个组件传递到另一组件

html - 类型错误 : Cannot read property 'File' of undefined

typescript - Angular 2 和模板 : Unterminated string literal. 在第 6 列 24

javascript - 如何在 NestJS 过滤器中使用 @Catch() 接口(interface)