JavaScript numbers to Words

前端 未结 24 1499
死守一世寂寞
死守一世寂寞 2020-11-22 14:39

I\'m trying to convert numbers into english words, for example 1234 would become: \"one thousand two hundred thirty four\".

My Tact

24条回答
  •  时光取名叫无心
    2020-11-22 14:56

    Here's a solution that will handle any integer value that fit's in a string. I've defined number scales up to "decillion", so this solution should be accurate up to 999 decillion. After which you get things like "one thousand decillion" and so on.

    JavaScript numbers start to fail around "999999999999999" so the convert function works with strings of numbers only.

    Examples:

    convert("365");
    //=> "three hundred sixty-five"
    
    convert("10000000000000000000000000000230001010109");
    //=> "ten thousand decillion two hundred thirty billion one million ten thousand one hundred nine"
    

    Code:

    var lt20 = ["", "one", "two", "three", "four", "five", "six", "seven","eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" ],
        tens = ["", "ten", "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eightty", "ninety" ],
        scales = ["", "thousand", "million", "billion", "trillion", "quadrillion", "quintillion", "sextillion", "septillion", "octillion", "nonillion", "decillion" ],
        max = scales.length * 3;
    
    function convert(val) {
        var len;
    
        // special cases
        if (val[0] === "-") { return "negative " + convert(val.slice(1)); }
        if (val === "0") { return "zero"; }
    
        val = trim_zeros(val);
        len = val.length;
    
        // general cases
        if (len < max) { return convert_lt_max(val); }
        if (len >= max) { return convert_max(val); }
    }
    
    function convert_max(val) {
        return split_rl(val, max)
            .map(function (val, i, arr) {
                if (i < arr.length - 1) {
                    return convert_lt_max(val) + " " + scales.slice(-1);
                }
                return convert_lt_max(val);
            })
            .join(" ");
    }       
    
    function convert_lt_max(val) {
        var l = val.length;
        if (l < 4) {
            return convert_lt1000(val).trim();
        } else {
            return split_rl(val, 3)
                .map(convert_lt1000)
                .reverse()
                .map(with_scale)
                .reverse()
                .join(" ")
                .trim();
        }
    }
    
    function convert_lt1000(val) {
        var rem, l;
    
        val = trim_zeros(val);
        l = val.length;
    
        if (l === 0) { return ""; }
        if (l < 3) { return convert_lt100(val); }
        if (l === 3) { //less than 1000
            rem = val.slice(1);
            if (rem) {
                return lt20[val[0]] + " hundred " + convert_lt1000(rem);
            } else {
                return lt20[val[0]] + " hundred";
            }
        }
    }
    
    function convert_lt100(val) {
        if (is_lt20(val)) { // less than 20
            return lt20[val];
        } else if (val[1] === "0") {
            return tens[val[0]];
        } else {
            return tens[val[0]] + "-" +  lt20[val[1]];
        }
    }
    
    
    function split_rl(str, n) {
        // takes a string 'str' and an integer 'n'. Splits 'str' into
        // groups of 'n' chars and returns the result as an array. Works
        // from right to left.
        if (str) {
            return Array.prototype.concat
                .apply(split_rl(str.slice(0, (-n)), n), [str.slice(-n)]);
        } else {
            return [];
        }
    }
    
    function with_scale(str, i) {
        var scale;
        if (str && i > (-1)) {
            scale = scales[i];
            if (scale !== undefined) {
                return str.trim() + " " + scale;
            } else {
                return convert(str.trim());
            }
        } else {
            return "";
        }
    }
    
    function trim_zeros(val) {
        return val.replace(/^0*/, "");
    }
    
    function is_lt20(val) {
        return parseInt(val, 10) < 20;
    }
    

提交回复
热议问题