最近做数据质量一直在跟各种“率”打交道,数据分析的结果往往都是类似“0.1234”的小数,但是页面需要展现的却是百分率,刚刚接触AS,就想自己写个小函数来理顺思路顺便解决问题。
小数转化百分数的逻辑并不复杂,但是也不能想的太简单,只把小数点后移两位肯定是不够的。首先,需要转化的对象没有固定的格式,甚至还有整数,而且对象默认是字符串类型,还涉及到一些进位和四舍五入的操作,所以要一步步的考虑全面。
1. 定义一个包含有三个参数的方法,三个参数按照顺序分别是需要转化的小数(字符串类型)、小数点后需要保留的位数以及是否允许四舍五入:
private function rateTransform(str:String, decimalsNum:int, ifRound:Boolean):String {};
2. 在普通情况下,传入的字符串会有固定的类似“1.23”的格式,这就意味着可以通过split()函数用小数点来分隔开整数和小数分别操作,如果传入的是整数,直接补上两个零return:
if (str == "0")
return str + "%";
// 分割整数和小数
var arr:Array = new Array;
arr = str.split(".");
// 如果传入的是整数 直接补位返回
if (arr.length <= 1)
return str + "00%";
// 整数串
var unit:String = arr[0];
// 小数串
var decimals:String = arr[1];
3. 如果参数中需要保留的小数位数小于或等于小数位,为了方便之后的截取和四舍五入操作,需要补零:
if (decimalsNum >= decimals.length) {
// 需要补充截取位和四舍五入位上的零
var sufNum:int = decimalsNum - decimals.length + 1;
var suffix:String = "";
for (var i:int = 0; i < sufNum; i++) {
suffix += "0";
}
// 补充后替换小数串
decimals = decimals + suffix;
}
4. 如果传入的Boolean类型为true,就需要进行四舍五入的进位处理,如果遇到满十进一,还需要将“一”加给整数串,但是如果小数串前几位为零,转化进位处理后需要将零补齐:
var decimalsRound:String;
if (ifRound) {
var decimalsCut:String = decimals.substring(0, decimalsNum + 1);
// 满五进一
if (int(decimalsCut.charAt(decimalsNum)) >= 5) {
decimalsRound = (int(decimalsCut.substring(0, decimalsNum)) + 1).toString();
// 满十进一
if (decimalsRound.length > decimalsNum) {
decimalsRound = decimalsRound.substring(1, decimalsNum + 1);
unit = (int(unit) + 1).toString();
// 补零处理以便小数点移动
} else if (decimalsRound.length < decimalsNum) {
var preNum:int = decimalsNum - decimalsRound.length
var prefix:String = "";
for (var ii:int = 0; ii < preNum; ii++) {
prefix += "0";
}
decimalsRound = prefix + decimalsRound;
}
} else
decimalsRound = decimalsCut.substring(0, decimalsNum);
} else
decimalsRound = decimals.substring(0, decimalsNum);
5.经过以上处理得到小数串,需要做最后的小数点移动处理,需要注意的是如果小数点右移两位后,小数点左边的第一位为零,就需要把重复的零去掉,如果小数点右边全为零则默认不显示(根据具体业务可以不做处理),最后补充上整数串与百分号就可以将处理结果返回:
if (decimalsRound.length > 2) {
// 去零处理
decimalsRound = int(decimalsRound.substring(0, 2)).toString()
var aft:String = decimalsRound.substring(2, decimalsRound.length);
// 根据业务需要处理
if(int(aft) != 0)
decimalsRound = decimalsRound + "." + aft;
} else
decimalsRound = int(decimalsRound).toString()
// 补充整数串与百分号
return (unit == "0"?"":unit) + decimalsRound.toString() + "%";
完整代码:
private function rateTransform(str:String, decimalsNum:int, ifRound:Boolean):String {
if (str == "0")
return str + "%";
// 分割整数和小数
var arr:Array = new Array;
arr = str.split(".");
// 如果传入的是整数 直接补位返回
if (arr.length <= 1)
return str + "00%";
// 整数串
var unit:String = arr[0];
// 小数串
var decimals:String = arr[1];
if (decimalsNum >= decimals.length) {
// 需要补充截取位和四舍五入位上的零
var sufNum:int = decimalsNum - decimals.length + 1;
var suffix:String = "";
for (var i:int = 0; i < sufNum; i++) {
suffix += "0";
}
// 补充后替换小数串
decimals = decimals + suffix;
}
var decimalsRound:String;
if (ifRound) {
var decimalsCut:String = decimals.substring(0, decimalsNum + 1);
// 满五进一
if (int(decimalsCut.charAt(decimalsNum)) >= 5) {
decimalsRound = (int(decimalsCut.substring(0, decimalsNum)) + 1).toString();
// 满十进一
if (decimalsRound.length > decimalsNum) {
decimalsRound = decimalsRound.substring(1, decimalsNum + 1);
unit = (int(unit) + 1).toString();
// 补零处理以便小数点移动
} else if (decimalsRound.length < decimalsNum) {
var preNum:int = decimalsNum - decimalsRound.length
var prefix:String = "";
for (var ii:int = 0; ii < preNum; ii++) {
prefix += "0";
}
decimalsRound = prefix + decimalsRound;
}
} else
decimalsRound = decimalsCut.substring(0, decimalsNum);
} else
decimalsRound = decimals.substring(0, decimalsNum);
if (decimalsRound.length > 2) {
// 去零处理
decimalsRound = int(decimalsRound.substring(0, 2)).toString()
var aft:String = decimalsRound.substring(2, decimalsRound.length);
// 根据业务需要处理
if(int(aft) != 0)
decimalsRound = decimalsRound + "." + aft;
} else
decimalsRound = int(decimalsRound).toString()
// 补充整数串与百分号
return (unit == "0"?"":unit) + decimalsRound.toString() + "%";
};