Как пребразовать число в текст на JavaScript?
Мне надо преобразовать строку в текст, например:
- 123 в "сто двадцать три";
- 351 в "триста пятьдесят один";
- 11 в "одиннадцать";
- -89 в "минус восемьдесят девять";
- И так далее.
Скрипт должен преобразовывать число от -999 до 999.
Как это можно сделать?
Ответы (2 шт):
Автор решения: Pet Linux
→ Ссылка
Это можно сделать так:
const min = -999,
max = 999;
// базовый текст чисел
const numberText = {
"0": "",
"00": "",
"1": "один",
"2": "два",
"3": "три",
"4": "четыре",
"5": "пять",
"6": "шесть",
"7": "семь",
"8": "восемь",
"9": "девять",
"10": "десять",
"11": "одиннадцать",
"12": "двенадцать",
"13": "тринадцать",
"14": "четырнадцать",
"15": "пятнадцать",
"16": "шестнадцать",
"17": "семнадцать",
"18": "восемнадцать",
"19": "девятнадцать",
"20": "двадцать",
"30": "тридцать",
"40": "сорок",
"50": "пятьдесят",
"60": "шестьдесят",
"70": "семьдесят",
"80": "восемьдесят",
"90": "девяносто",
"100": "сто",
"200": "двести",
"300": "триста",
"400": "четыреста",
"500": "пятьсот",
"600": "шестьсот",
"700": "семьсот",
"800": "восемьсот",
"900": "девятьсот",
};
// добавление поддержки негативных чисел (например, "-1")
for (let key in numberText) {
numberText["-" + key] = numberText[key];
}
function numberToText(n) {
// оригинальное число n
const originalN = n;
// в эту переменную будет записываться текстовое представление числа
let stringDigit = "";
// эта переменная для различных операций с числом, как со строкой
let nStr = n.toString();
// преобразование Math.abs(n) для того, чтобы было легче оперировать с числом
n = Math.abs(n);
if (nStr.startsWith("-")) {
// проверяем, чтобы число было в диапазоне, чтобы не получилось "минус "
stringDigit += (-n >= -999) ? "минус " : ""; // пробел тут обязателен, для того, чтобы текст не слился
// убираем - (минус) с начала строки nStr
nStr = nStr.slice(1);
}
// тут начинается главное преобразование
if (n >= 1 && n <= 19) { // если n в диапазоне (1, 19)
// то просто берём значение с ключом [n] из объекта numberText
stringDigit += numberText[n];
} else if (n >= 20 && n <= 99) { // если n в диапазоне (20, 99)
// то мы сначала берём текстовое представление с первого числа, например, с 26 это будет 20
stringDigit += numberText[nStr[0] + "0"];
// потом проверяем, если существует цифра, отличное от 0 в конце числа
if (!n.toString().endsWith("0")) {
// и если так, то добавляем остаток от числа n % 10, например, с 26 будет 6
stringDigit += " " + numberText[n % 10];
}
} else if (n >= 100 && n <= 999) { // если n в диапазоне (100, 999)
// сначала добавляем текстовое представление разряда сотен
stringDigit += numberText[nStr[0] + "00"];
// это переменная для того, чтобы получить разряд десятков
let twoSignN = (n % 100).toString();
// проверяем остаток (резряд единиц/десятков), например, если n = 123, то остаток будет 23
if (twoSignN >= 1 && twoSignN <= 19) { // если разряд десятков в диапазоне (1, 19)
// добавляем текст разряда десятков
stringDigit += " " + numberText[twoSignN];
} else {
stringDigit += " " + numberText[twoSignN[0] + "0"];
}
// если разряд единиц отличный от 0
if (!nStr.endsWith("0") && (twoSignN >= 20 && twoSignN <= 99)) {
// то добавляем текстовое представление разряда единиц
stringDigit += " " + numberText[twoSignN[1]];
}
}
// убрать лишние пробелы в текстовом представлении числа
stringDigit = stringDigit.replaceAll(" ", " ");
stringDigit = stringDigit.trim();
return stringDigit || originalN.toString();
}
Скрипт объяснён в комментариях.
Пример того, как его можно использовать (и демонстрация того, как он работает):
const min=-999,max=999;const numberText={0:"","00":"",1:"один",2:"два",3:"три",4:"четыре",5:"пять",6:"шесть",7:"семь",8:"восемь",9:"девять",10:"десять",11:"одиннадцать",12:"двенадцать",13:"тринадцать",14:"четырнадцать",15:"пятнадцать",16:"шестнадцать",17:"семнадцать",18:"восемнадцать",19:"девятнадцать",20:"двадцать",30:"тридцать",40:"сорок",50:"пятьдесят",60:"шестьдесят",70:"семьдесят",80:"восемьдесят",90:"девяносто",100:"сто",200:"двести",300:"триста",400:"четыреста",500:"пятьсот",600:"шестьсот",700:"семьсот",800:"восемьсот",900:"девятьсот"};for(let key in numberText){numberText["-"+key]=numberText[key]}function numberToText(n){const originalN=n;let stringDigit="";let nStr=n.toString();n=Math.abs(n);if(nStr.startsWith("-")){stringDigit+=-n>=-999?"минус ":"";nStr=nStr.slice(1)}if(n>=1&&n<=19){stringDigit+=numberText[n]}else if(n>=20&&n<=99){stringDigit+=numberText[nStr[0]+"0"];if(!n.toString().endsWith("0")){stringDigit+=" "+numberText[n%10]}}else if(n>=100&&n<=999){stringDigit+=numberText[nStr[0]+"00"];let twoSignN=(n%100).toString();if(twoSignN>=1&&twoSignN<=19){stringDigit+=" "+numberText[twoSignN]}else{stringDigit+=" "+numberText[twoSignN[0]+"0"]}if(!nStr.endsWith("0")&&(twoSignN>=20&&twoSignN<=99)){stringDigit+=" "+numberText[twoSignN[1]]}}stringDigit=stringDigit.replaceAll(" "," ");stringDigit=stringDigit.trim();return stringDigit||originalN.toString()}
let currentNumber = 0;
const numberShowSpan = document.querySelector("#show-number"),
numberTextShowSpan = document.querySelector("#show-number-text"),
incrementButton = document.querySelector("#increment"),
decrementButton = document.querySelector("#decrement");
display();
incrementButton.addEventListener("click", () => {
currentNumber++;
display();
});
decrementButton.addEventListener("click", () => {
currentNumber--;
display();
});
function display() {
numberShowSpan.textContent = currentNumber;
numberTextShowSpan.textContent = numberToText(currentNumber);
}
<p>Текущее число n: <b><span id="show-number">0</span></b></p>
<p>
Текущее представление числа n в текстовом формате: <b><span id="show-number-text"></span></b>
</p>
<button id="increment">Увеличить</button>/<button id="decrement">Уменьшить</button>
(Первая строка минифицирована для того, чтобы было удобнее читать скрипт демонстрации - для основного скрипта смотрите выше).
Автор решения: Stanislav Volodarskiy
→ Ссылка
const numberInWords = n => {
if (Number.isNaN(n)) {
return '?';
}
if (n === 0) {
return 'ноль';
}
const result = [];
if (n < 0) {
result.push('минус');
n = -n;
}
const u = n % 10;
const t = Math.floor(n % 100 / 10);
const h = Math.floor(n / 100);
if (h > 0) {
result.push([
undefined, 'сто' , 'двести' , 'триста' , 'четыреста',
'пятьсот', 'шестьсот', 'семьсот', 'восемьсот', 'девятьсот'
][h]);
}
if (t === 1) {
result.push([
'десять' , 'одиннадцать' ,
'двенадцать' , 'тринадцать' ,
'четырнадцать', 'пятнадцать' ,
'шестнадцать' , 'семнадцать' ,
'восемнадцать', 'девятнадцать'
][u]);
} else {
if (t > 1) {
result.push([
undefined , undefined ,
'двадцать' , 'тридцать' ,
'сорок' , 'пятьдесят',
'шестьдесят' , 'семьдесят',
'восемьдесят', 'девяносто'
][t]);
}
if (u > 0) {
result.push([
undefined, 'один' , 'два' , 'три' , 'четыре',
'пять' , 'шесть', 'семь', 'восемь', 'девять'
][u]);
}
}
return result.join(' ');
};
const main = () => {
const number = document.getElementById('number');
const text = document.getElementById('text');
number.oninput = () => {
text.textContent = numberInWords(parseInt(number.value));
};
};
main();
<label for="name">Число [-999, 999]:</label>
<input type="number" id="number">
<br>
<span id="text">?</span>