You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js基于Mongoose的评分平均计算异常问题求助

问题根因

你遇到的计算异常本质是字符串拼接而非数值相加导致的:

  • 前端提交到req.body的所有criteria参数的值都是字符串类型(比如"8"而非数字8)
  • 你写的avg函数直接执行a + b,如果操作数是字符串就会触发拼接逻辑:10个"8"相加会得到"8888888888",除以10得到888888888.8,再和"8"拼接得到"888888888.88",最后除以2就得到了你看到的4444444这类异常值。
修复方案

1. 快速修复:直接转换数值类型

在取值的时候统一把字符串转成数字即可,修改你创建Rates实例的部分:

const rate = new Rates({
  project,
  voter,
  votes:{
    participant: participants[i],
    // 每个criteria取值时转成数字
    criteria1: Number(criteria1[i]),
    criteria2: Number(criteria2[i]),
    criteria3: Number(criteria3[i]),
    criteria4: Number(criteria4[i]),
    criteria5: Number(criteria5[i]),
    criteria6: Number(criteria6[i]),
    criteria7: Number(criteria7[i]),
    criteria8: Number(criteria8[i]),
    criteria9: Number(criteria9[i]),
    criteria10: Number(criteria10[i]),
    criteria11: Number(criteria11[i]),
    criteria12: criteria12[i],
    // 计算时也统一转数字避免出错
    average: avg([
      avg([criteria1, criteria2, criteria3, criteria4, criteria5, criteria6, criteria7, criteria8, criteria9, criteria10].map(c => Number(c[i]))),
      Number(criteria11[i])
    ])
  }
})

2. 优化方案:改造avg函数从根源避免类型问题

可以给avg函数加上数值转换逻辑,以后不管传的是字符串还是数字都能正常计算,非法数值默认按0处理,可根据业务需求调整:

const avg = (args) => {
  const numbers = args.map(item => Number(item) || 0);
  return numbers.reduce((a, b) => a + b, 0) / numbers.length;
};

改造后你原来的计算代码不用修改也能正常输出正确结果。

额外优化建议

你现在手写10个criteria的方式冗余度很高,可以改成动态取值,后续增减评分项也不用改逻辑:

// 动态生成criteria1到criteria10的数值数组
const firstTen = Array.from({length:10}, (_, idx) => Number(req.body[`criteria${idx+1}`][i]));
const firstAvg = avg(firstTen);
const finalAvg = avg([firstAvg, Number(criteria11[i])]);

内容的提问来源于stack exchange,提问作者Ayaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 05:09:00