数字太长看花眼?一招教它排好队:千分位处理的实现

0 阅读4分钟

前言

面试的话,手撕代码肯定是少不了的。最近看到一个非常有意思的题目:如何实现千分位处理?比如你💳里面的余额是 35168461321.542345,怎么把它变成 35,168,461,321.54

这时候你可千万别来一句:我卡里没那么多... 😄

思路

其实千分位格式化一点都不神秘,本质就是 “拆数字→加逗号→拼回去” 的小把戏。不管是字符串拼接还是数组操作,实现这个效果,核心思路就三步:先固定小数位数,再拆分整数和小数部分,最后给整数部分挨个加逗号分隔

方法一:字符串拼接大法

const num = 35168461321.542345;
function toThousand(num) {
    // 第一步:保留两位小数,解决小数位数杂乱问题
    num = num.toFixed(2);
    // 转成字符串,方便拆分和遍历
    let str = num.toString();
   
    // 拆分整数和小数部分
    let [int, decimal] = str.split('.');
    let result = '';
    
    // 从右往左遍历整数部分,每3位加逗号
    for (let i = int.length - 1, count = 1; i >= 0; i--, count++) {
        result = int[i] + result;
        // 每3位加逗号,且不是第一位时才加
        if (count % 3 === 0 && i !== 0) {
            result = ',' + result;
        }
    }
    // 拼接整数和小数部分
    return result + '.' + decimal;
}
console.log(toThousand(num)); // 输出 35,168,461,321.54

image.png

这个方法就像手工串珠子,从后往前把数字一个个拼回去,每拼 3 个就加个逗号 “隔档”,逻辑特别直观,新手一看就能懂。遍历的时候用 count 计数,数到 3 就塞个逗号,还得注意 i !== 0 这个小细节 —— 要是忘了这个,数字最开头会多一个逗号,面试就可能挂啦。

方法二:数组操作版

const num = 35168461321.542345;
function toThousand(num) {
    num = num.toFixed(2);
    
    // 拆分整数和小数部分,用call兼容更多场景
    const [integer, decimal] = String.prototype.split.call(num, '.');
    const res = [];
    let len = 0;    
    
    // 从右往左遍历整数
    for (let i = integer.length - 1; i >= 0; i--) {
        // 往数组开头塞数字
        res.unshift(integer[i]);
        len++;
        // 每3位加逗号,且不是第一位
        if (len % 3 === 0 && i !== 0) {
            res.unshift(',');
        }
    }
    // 数组转字符串,拼接小数部分
    const str = res.join('') + '.' + decimal;
    return str;
}
console.log(toThousand(num)); // 输出 35,168,461,321.54

image.png

这个方法相当于用数组当 “收纳盒”,每次把数字往盒子开头放,数够 3 个就塞个逗号进去,最后把盒子里的东西连成字符串。用 unshift 比字符串拼接少了点 “倒腾” 的步骤。

方法三:先转数组反向处理版

const num = 35168461321.542345;
function toThousand(num) {
    const fixedNum = num.toFixed(2);
    const [int, decimal] = fixedNum.split('.');
    
    // 整数部分转数组并反转,方便从左往右数3位
    const reverseInt = int.split('').reverse();
    const result = [];
    reverseInt.forEach((char, index) => {
        result.push(char);
        // 每3位加逗号,且不是最后一位
        if ((index + 1) % 3 === 0 && index !== reverseInt.length - 1) {
            result.push(',');
        }
    });
    // 反转回来并拼接
    const finalInt = result.reverse().join('');
    return `${finalInt}.${decimal}`;
}
console.log(toThousand(num)); // 输出 35,168,461,321.54

image.png

把整数反转后,从左往右每 3 位加逗号,最后再反转回来,不用倒着遍历计数,逻辑更贴近日常 “数 3 位” 的习惯。

方法四:正则表达式 “魔法版” (面试别用)

const num = 35168461321.542345;
function toThousand(num) {
    // 先保留两位小数,避免小数位数干扰
    const fixedNum = num.toFixed(2);
    
    // 正则核心:匹配整数部分从右往左每三位(非开头)
    return fixedNum.replace(/\d(?=(\d{3})+\.)/g, '$&,');
}
console.log(toThousand(num)); // 输出 35,168,461,321.54

image.png

\d(?=(\d{3})+.)“正向预查”,意思是 “匹配一个数字,这个数字后面跟着若干个 3 位数字,最后是小数点”,然后把匹配到的数字替换成 “数字 + 逗号”,完美实现千分位分隔,不用手动遍历。但是面试别用,面试官肯定不想看到这种答案😳

方法五:Intl.NumberFormat 原生 API 版(面试别用,只做扩展)

const num = 35168461321.542345;
function toThousand(num) {
    // 配置:中文环境、保留2位小数、只显示数字
    return new Intl.NumberFormat('zh-CN', {
        minimumFractionDigits: 2,
        maximumFractionDigits: 2
    }).format(num);
}
console.log(toThousand(num)); // 输出 35,168,461,321.54

image.png

JS 自带的国际化 API,专门处理数字格式化,兼容多语言 / 多地区规则,大厂项目里超常用,几乎不用自己写逻辑,依旧还是面试别用,以后拿 offer 有你用的地方 ^_^

结语

千分位处理玩法千千万,无论是手写循环、数组反转,还是正则一键搞定,甚至直接用原生 API 偷懒,本质都是让长数字变得更易读。日常开发里,懂原理能手写,上项目用 API,灵活切换就够稳了。

面试还是推荐前三种 😄