JavaScript numbers to Words

前端 未结 24 1192
死守一世寂寞
死守一世寂寞 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:47

    I think, I have solution that's simpler and easier to understand; it goes by slicing the number, it works up to 99 lakhs crore.

    function convert_to_word(num, ignore_ten_plus_check) {
    
    var ones = [];
    var tens = [];
    var ten_plus = [];
    ones["1"] = "one";
    ones["2"] = "two";
    ones["3"] = "three";
    ones["4"] = "four";
    ones["5"] = "five";
    ones["6"] = "six";
    ones["7"] = "seven";
    ones["8"] = "eight";
    ones["9"] = "nine";
    
    ten_plus["10"] = "ten";
    ten_plus["11"] = "eleven";
    ten_plus["12"] = "twelve";
    ten_plus["13"] = "thirteen";
    ten_plus["14"] = "fourteen";
    ten_plus["15"] = "fifteen";
    ten_plus["16"] = "sixteen";
    ten_plus["17"] = "seventeen";
    ten_plus["18"] = "eighteen";
    ten_plus["19"] = "nineteen";
    
    tens["1"] = "ten";
    tens["2"] = "twenty";
    tens["3"] = "thirty";
    tens["4"] = "fourty";
    tens["5"] = "fifty";
    tens["6"] = "sixty";
    tens["7"] = "seventy";
    tens["8"] = "eighty";
    tens["9"] = "ninety";   
    
        var len = num.length;
    
        if(ignore_ten_plus_check != true && len >= 2) {
            var ten_pos = num.slice(len - 2, len - 1);
            if(ten_pos == "1") {
                return ten_plus[num.slice(len - 2, len)];
            } else if(ten_pos != 0) {
                return tens[num.slice(len - 2, len - 1)] + " " + ones[num.slice(len - 1, len)];
            }
        }
    
        return ones[num.slice(len - 1, len)];
    
    }
    
    function get_rupees_in_words(str, recursive_call_count) {
      if(recursive_call_count > 1) {
            return "conversion is not feasible";
        }
        var len = str.length;
        var words = convert_to_word(str, false);
        if(len == 2 || len == 1) {
        if(recursive_call_count == 0) {
            words = words +" rupees";
        }
            return words;
        }
        if(recursive_call_count == 0) {
            words = " and " + words +" rupees";
        }
    
    
    
    var hundred = convert_to_word(str.slice(0, len-2), true);
      words = hundred != undefined ? hundred + " hundred " + words : words;
        if(len == 3) {
            return words;
        }
    
    var thousand = convert_to_word(str.slice(0, len-3), false);
    words = thousand != undefined ? thousand  + " thousand " + words : words;
    if(len <= 5) {
        return words;
    }
    
    var lakh = convert_to_word(str.slice(0, len-5), false);
    words =  lakh != undefined ? lakh + " lakh " + words : words;
    if(len <= 7) {
        return words;
    }
    
    recursive_call_count = recursive_call_count + 1;
    return get_rupees_in_words(str.slice(0, len-7), recursive_call_count) + " crore " + words;
    }
    

    Please check out my code pen

    0 讨论(0)
  • 2020-11-22 14:48
    function intToEnglish(number){
    
    var NS = [
        {value: 1000000000000000000000, str: "sextillion"},
        {value: 1000000000000000000, str: "quintillion"},
        {value: 1000000000000000, str: "quadrillion"},
        {value: 1000000000000, str: "trillion"},
        {value: 1000000000, str: "billion"},
        {value: 1000000, str: "million"},
        {value: 1000, str: "thousand"},
        {value: 100, str: "hundred"},
        {value: 90, str: "ninety"},
        {value: 80, str: "eighty"},
        {value: 70, str: "seventy"},
        {value: 60, str: "sixty"},
        {value: 50, str: "fifty"},
        {value: 40, str: "forty"},
        {value: 30, str: "thirty"},
        {value: 20, str: "twenty"},
        {value: 19, str: "nineteen"},
        {value: 18, str: "eighteen"},
        {value: 17, str: "seventeen"},
        {value: 16, str: "sixteen"},
        {value: 15, str: "fifteen"},
        {value: 14, str: "fourteen"},
        {value: 13, str: "thirteen"},
        {value: 12, str: "twelve"},
        {value: 11, str: "eleven"},
        {value: 10, str: "ten"},
        {value: 9, str: "nine"},
        {value: 8, str: "eight"},
        {value: 7, str: "seven"},
        {value: 6, str: "six"},
        {value: 5, str: "five"},
        {value: 4, str: "four"},
        {value: 3, str: "three"},
        {value: 2, str: "two"},
        {value: 1, str: "one"}
      ];
    
      var result = '';
      for (var n of NS) {
        if(number>=n.value){
          if(number<=20){
            result += n.str;
            number -= n.value;
            if(number>0) result += ' ';
          }else{
            var t =  Math.floor(number / n.value);
            var d = number % n.value;
            if(d>0){
              return intToEnglish(t) + ' ' + n.str +' ' + intToEnglish(d);
            }else{
              return intToEnglish(t) + ' ' + n.str;
            }
    
          }
        }
      }
      return result;
    }
    
    0 讨论(0)
  • 2020-11-22 14:51

    I know this problem had solved 3 years ago. I am posting this SPECIALLY FOR INDIAN DEVELOPERS

    After spending some time in googling and playing with others code i made a quick fix and reusable function works well for numbers upto 99,99,99,999. use : number2text(1234.56); will return ONE THOUSAND TWO HUNDRED AND THIRTY-FOUR RUPEE AND FIFTY-SIX PAISE ONLY . enjoy !

    function number2text(value) {
        var fraction = Math.round(frac(value)*100);
        var f_text  = "";
    
        if(fraction > 0) {
            f_text = "AND "+convert_number(fraction)+" PAISE";
        }
    
        return convert_number(value)+" RUPEE "+f_text+" ONLY";
    }
    
    function frac(f) {
        return f % 1;
    }
    
    function convert_number(number)
    {
        if ((number < 0) || (number > 999999999)) 
        { 
            return "NUMBER OUT OF RANGE!";
        }
        var Gn = Math.floor(number / 10000000);  /* Crore */ 
        number -= Gn * 10000000; 
        var kn = Math.floor(number / 100000);     /* lakhs */ 
        number -= kn * 100000; 
        var Hn = Math.floor(number / 1000);      /* thousand */ 
        number -= Hn * 1000; 
        var Dn = Math.floor(number / 100);       /* Tens (deca) */ 
        number = number % 100;               /* Ones */ 
        var tn= Math.floor(number / 10); 
        var one=Math.floor(number % 10); 
        var res = ""; 
    
        if (Gn>0) 
        { 
            res += (convert_number(Gn) + " CRORE"); 
        } 
        if (kn>0) 
        { 
                res += (((res=="") ? "" : " ") + 
                convert_number(kn) + " LAKH"); 
        } 
        if (Hn>0) 
        { 
            res += (((res=="") ? "" : " ") +
                convert_number(Hn) + " THOUSAND"); 
        } 
    
        if (Dn) 
        { 
            res += (((res=="") ? "" : " ") + 
                convert_number(Dn) + " HUNDRED"); 
        } 
    
    
        var ones = Array("", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX","SEVEN", "EIGHT", "NINE", "TEN", "ELEVEN", "TWELVE", "THIRTEEN","FOURTEEN", "FIFTEEN", "SIXTEEN", "SEVENTEEN", "EIGHTEEN","NINETEEN"); 
    var tens = Array("", "", "TWENTY", "THIRTY", "FOURTY", "FIFTY", "SIXTY","SEVENTY", "EIGHTY", "NINETY"); 
    
        if (tn>0 || one>0) 
        { 
            if (!(res=="")) 
            { 
                res += " AND "; 
            } 
            if (tn < 2) 
            { 
                res += ones[tn * 10 + one]; 
            } 
            else 
            { 
    
                res += tens[tn];
                if (one>0) 
                { 
                    res += ("-" + ones[one]); 
                } 
            } 
        }
    
        if (res=="")
        { 
            res = "zero"; 
        } 
        return res;
    }
    
    0 讨论(0)
  • 2020-11-22 14:53

    This is a simple ES6+ number to words function. You can simply add 'illions' array to extend digits. American English version. (no 'and' before the end)

    // generic number to words
    
    let digits  = ['','one','two','three','four', 'five','six','seven','eight','nine','ten','eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen'];
    let ties    = ['', '', 'twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'];
    let illions = ['', 'thousand', 'million', 'billion', 'trillion'].reverse()
    
    let join = (a, s) => a.filter(v => v).join(s || ' ')
    
    let tens = s => 
        digits[s] || 
        join([ties[s[0]], digits[s[1]]], '-') // 21 -> twenty-one
    
    let hundreds = s => 
        join(
            (s[0] !== '0' ? [digits[s[0]], 'hundred'] : [])
                .concat( tens(s.substr(1,2)) )  )
    
    let re = '^' + '(\\d{3})'.repeat(illions.length) + '$'
    
    let numberToWords = n => 
        // to filter non number or '', null, undefined, false, NaN
        isNaN(Number(n)) || !n && n !== 0 
            ? 'not a number'
            : Number(n) === 0 
                ? 'zero'  
                : Number(n) >= 10 ** (illions.length * 3)
                    ? 'too big'
                    : String(n)
                        .padStart(illions.length * 3, '0')
                        .match(new RegExp(re))
                        .slice(1, illions.length + 1)
                        .reduce( (a, v, i) => v === '000' ? a : join([a, hundreds(v), illions[i]]), '')
    
    
    // just for this question.
    
    let update = () => {
        let value = document.getElementById('number').value
        document.getElementById('container').innerHTML = numberToWords(value)
    }
    
    0 讨论(0)
  • 2020-11-22 14:54

    Your problem is already solved but I am posting another way of doing it just for reference.

    The code was written to be tested on node.js, but the functions should work fine when called within the browser. Also, this only handles the range [0,1000000], but can be easily adapted for bigger ranges.

    // actual  conversion code starts here
    
    var ones = ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
    var tens = ['', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'];
    var teens = ['ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'];
    
    function convert_millions(num) {
      if (num >= 1000000) {
        return convert_millions(Math.floor(num / 1000000)) + " million " + convert_thousands(num % 1000000);
      } else {
        return convert_thousands(num);
      }
    }
    
    function convert_thousands(num) {
      if (num >= 1000) {
        return convert_hundreds(Math.floor(num / 1000)) + " thousand " + convert_hundreds(num % 1000);
      } else {
        return convert_hundreds(num);
      }
    }
    
    function convert_hundreds(num) {
      if (num > 99) {
        return ones[Math.floor(num / 100)] + " hundred " + convert_tens(num % 100);
      } else {
        return convert_tens(num);
      }
    }
    
    function convert_tens(num) {
      if (num < 10) return ones[num];
      else if (num >= 10 && num < 20) return teens[num - 10];
      else {
        return tens[Math.floor(num / 10)] + " " + ones[num % 10];
      }
    }
    
    function convert(num) {
      if (num == 0) return "zero";
      else return convert_millions(num);
    }
    
    //end of conversion code
    
    //testing code begins here
    
    function main() {
      var cases = [0, 1, 2, 7, 10, 11, 12, 13, 15, 19, 20, 21, 25, 29, 30, 35, 50, 55, 69, 70, 99, 100, 101, 119, 510, 900, 1000, 5001, 5019, 5555, 10000, 11000, 100000, 199001, 1000000, 1111111, 190000009];
      for (var i = 0; i < cases.length; i++) {
        console.log(cases[i] + ": " + convert(cases[i]));
      }
    }
    
    main();

    0 讨论(0)
  • 2020-11-22 14:55

    I am providing here my solution for converting numbers to the equivalent English words using the Single Loop String Triplets (SLST) Method which I have published and explained in detail here at Code Review with illustration graphics.

    Simple Number to Words using a Single Loop String Triplets in JavaScript

    The concept is simple and easily coded and is also very efficient and fast. The code is very short compared with other alternative methods described in this article.

    The concept also permits the conversion of very vary large numbers as it does not rely on using the numeric/math function of the language and therefore avoids any limitations.

    The Scale Array may be increased by adding more scale names if required after "Decillion".

    A sample test function is provided below to generate numbers from 1 to 1099 as an example.

    A full fancy version is available that caters for adding the word "and" and commas between the scales and numbers to align with the UK and US ways of spelling the numbers.

    Hope this is useful.

    /************************************************************/
    function NumToWordsInt(NumIn) {
    /************************************************************
    * Convert Integer Numbers to English Words
    * Using the Single Loop String Triplets Method
    * @Param : {Number}  The number to be converted
    *                    For large numbers use a string
    * @Return: {String}  Wordified Number (Number in English Words)
    * @Author: Mohsen Alyafei 10 July 2019
    * @Notes : Call separately for whole and for fractional parts.
    *          Scale Array may be increased by adding more scale
    *          names if required after Decillion.
    /************************************************************/
      
     if (NumIn==0) return "Zero";
     var  Ones  = ["", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"],
          Tens  = ["", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"],
          Scale = ["", "Thousand", "Million", "Billion", "Trillion", "Quadrillion", "Quintillion", "Sextillion", "Septillion", "Octillion", "Nonillion", "Decillion"],
          N1, N2, Sep, j, i, h, Trplt, tns="", NumAll = "";
     NumIn += "";                                            // Make NumIn a String
    //----------------- code starts -------------------
     NumIn = "0".repeat(NumIn.length * 2 % 3) + NumIn;       //Create shortest string triplets 0 padded
     j = 0;                                                  //Start with the highest triplet from LH
        for (i = NumIn.length / 3 - 1; i >= 0; i--) {        //Loop thru number of triplets from LH most
          Trplt = NumIn.substring(j, j + 3);                 //Get a triplet number starting from LH
          if (Trplt !="000") {                               //Skip empty trplets
            Sep = Trplt[2] !="0" ? "-":" ";                  //Dash only for 21 to 99
            N1 = Number(Trplt[0]);                           //Get Hundreds digit
            N2 = Number(Trplt.substr(1));                    //Get 2 lowest digits (00 to 99) 
            tns = N2 > 19 ? Tens[Number(Trplt[1])] + Sep + Ones[Number(Trplt[2])] : Ones[N2];
            NumAll += ((h = N1>0 ? Ones[N1] + " Hundred": "") + " " + tns).trim() + " " + Scale[i]+ " "; 
          }
          j += 3;                                            //Next lower triplets (move to RH)
        }
    //----------------- code Ends --------------------
     return NumAll.trim();                                   //Return trimming excess spaces if any
    }
    
    
    
    // ----------------- test sample -----------------
    console.log(NumToWordsInt(67123))
    console.log(NumToWordsInt(120003123))
    console.log(NumToWordsInt(123999))
    console.log(NumToWordsInt(789123))
    console.log(NumToWordsInt(100178912))
    console.log(NumToWordsInt(777))
    console.log(NumToWordsInt(999999999))
    console.log(NumToWordsInt(45))

    0 讨论(0)
提交回复
热议问题