互联网产品离不开数据处理,数据处理有一些基本的原则包括:准确性、完整性、一致性、保密性、及时性。
我在最近的项目中就遇到了一个关于 准确性 和 完整性 的问题。
具体是这样:我们项目中有使用各种 Chart 来展示数据的功能,这些数据根据不同的类型和单位会为其加上前缀、后缀或者省略小数。比如:type = percent 数据后加 %,type = integer 数据不能有小数位,type = currency 数据前加 $ 等等。
问题出在 percent类型 的数据,有些数据如果按百分比来计算通常不会大于 1%,比如彩票中一等奖的概率。这个时候如果要比较两个数据选出具有更优表现的数据,小数点就需要多保留一到两位。
举个例子,假如百分比保留1位小数。同样是省略后 0.1% 的两个数据,一个 0.01% 另一个 0.04%,两者的差距可能是很大的。
如下图,虽然数据很小但是表现在 Chart 上差距是很明显的
我们目前的解决方案是判断数据如果 0.0% < X < 0.1% 就保留两位小数,其余情况保留一位小数。
function formatPercentRounding(data) {
const value = data, result = '0.0%';
// 0.0% < X < 0.1%
const decimalDigits = (value > 0 && value * 1000 < 1) ? 2 : 1;
if (value) {
result = (Math.round(value * 1000)/10).toFixed(decimalDigits) + '%';
}
return result;
}
之所以使用这种比较直接的方式是因为项目中的数据类型已经确定,而且对数字的处理逻辑没有统一在一个文件中。这是大型项目经常遇到的问题,起到相同作用的代码因为一些小的差别而分别写在管理各自功能的文件里。
如果项目重构这些都是需要优化的地方。针对这篇文章提到的数字缩写的问题,可以有两种处理方案。
一种是维护一个 config.json,如:
[
{
chart: 'bar',
numberRules: [
{
type: 'integer',
decimalDigits: 0
},
{
type: 'percent',
decimalDigits: 2,
suffix: '%'
}
]
},
{
chart: 'grid',
numberRules: [
{
type: 'currency',
decimalDigits: 1,
prefix: '$'
},
{
type: 'percent',
decimalDigits: 3,
suffix: '%'
}
]
},
...
]
或者将代码放在一个统一的方法中处理:
const method = (chartType, data) => {
let decimalDigits = 1;
switch (chartType) {
case 'grid':
decimalDigits = 2;
...
break;
...
default:
break;
}
return data.toFixed(decimalDigits);
}
两种方法都能解决问题,但是推荐第一种。我们可以直接把 config 文件存入数据库,这样我们就可以统一维护一个表,不管是前端来处理数据还是后端来处理都能遵守相同的规则。
以上就是我在实践中遇到的关于数据颗粒度的一个小问题以及对它的思考,谢谢