-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[js] 第114天 写一个把数字转成中文的方法,例如:101转成一百零一 #1039
Comments
const digitChar = ['', ...'一二三四五六七八九']
const posChar = ['', ...'十百千万 亿']
const placeholder = '零'
function toChineseNumeralUnder万(digits) {
let revDigits = digits.split('').reverse()
let result = ''
for (let pos = 0; pos < revDigits.length; pos++) {
const digit = Number(revDigits[pos])
if (digit)
{ result = posChar[pos] + result }
if (digit !== 1 || pos !== 1)
{ result = digitChar[digit] + result }
if (!digit && pos && result && !result.startsWith(placeholder))
{ result = placeholder + result }
}
return result
}
function toChineseNumeralUnder亿(digits) {
let highPart = toChineseNumeralUnder万(digits.slice(-8, -4))
if (highPart)
{ highPart += posChar[4] }
let lowPart = toChineseNumeralUnder万(digits.slice(-4))
return highPart + lowPart
}
function toChineseNumeral(digits) {
let fragment = ''
const result = []
for (const digit of digits.split('').reverse()) {
if (fragment.length === 8) {
result.unshift(toChineseNumeralUnder亿(fragment))
fragment = ''
}
fragment = digit + fragment
}
result.unshift(toChineseNumeralUnder亿(fragment))
if (result[0].startsWith(placeholder))
{ result[0] = result[0].slice(1) }
return result.join(posChar[8]) || placeholder
}
toChineseNumeral('0')
// => '零'
toChineseNumeral('101')
// => '一百零一'
toChineseNumeral('1000001')
// => '一百万零一'
toChineseNumeral('123456708')
// => '一亿二千三百四十五万六千七百零八'
toChineseNumeral('3274823947329471041041234567080')
// => '三百二十七万四千八百二十三亿九千四百七十三万二千九百四十七亿一千零四十一万零四百一十二亿三千四百五十六万七千零八十' 函数名很弱智,不要在意( |
@t532 这函数名中英文结合呢,不错不错! |
你好, numToChinese('121')
// => '壹贰拾壹百'
numToChinese('12147238372')
// => '壹亿贰壹undefined肆千柒拾贰拾叁百捌千叁万柒百贰undefined' |
唔~我在改改··位数只写到亿,下钟后在改改,感谢大佬指教 |
toChineseNumeral('1000001'); // expected: 一百万零一 |
试着修了一下,现在可以了。 |
/*
* @param {Number} 数字
* @return {String} 中文数字
*
*/
var arg = process.argv.slice(2)[0] + '';//node命令参数
console.log(CN_Number(arg));
function CN_Number(num) {
let str = num + '';
let arr = [];
let res = [];
for (let i = str.length-1; i >=0; i -= 4) {
arr.unshift(str.slice(i-4, i))
}
while (arr.length) {
res.unshift(arr.splice(-3, 3))
}
let block=['亿','万',''];
res = res.map(item =>{
if(item.length<3) item.unshift('');
return item.map((n,index) => {
let res = cn_fy(n);
res+=res?block[index]:"";
return res;
})
});
let cn_res='';
res.forEach((a)=>{
a.forEach(b=>{
cn_res+=b;
})
})
return cn_res
function cn_fy(n) {
let unit = ['千', '百', '十'];
let nums = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
let res = '';
for (let i = 0; i < n.length; ++i) {
if (n[i] == 0) res += '零'
else res += nums[n[i]] + (unit[i] || '')
}
while(res[0]==='零'){
res=res.substring(1)
}//去左零
while(res[res.length-1]==='零'){
res=res.substring(0,res.length-1)
}//去右零
while(res.indexOf('零零')>-1){
res=res.replace('零','')
}//去连续零
return res;
}
} |
function toChineseNumeral(n) {
let units = ['', '十', '百', '千'];
let numbers = '零一二三四五六七八九'.split('');
let alternateTwo = '两';
/**
* 按 length 把 str 切割,然后每段由 callback 来处理
* 后用 unit 连接,同时处理段之间要不要加零
*/
let fragmentFactory = (length, unit, callback) => {
let fn = strNum => {
if(strNum.length === 0) return '';
let tail = strNum.substring(strNum.length - length, strNum.length);
let head = strNum.substring(0, strNum.length - length);
let headResolved = fn(head);
if (headResolved.length > 0) {
headResolved += unit;
if (tail.match(/^0+[1-9]/)) {
headResolved += numbers[0];
}
}
return headResolved + callback(tail.replace(/^0+/, ''));
};
return fn;
}
/**
* 处理万以内的数字
*/
let resolve4 = partition => {
let digits = partition.split('');
let retStr = '';
for(let i = 0; i < digits.length; i++) {
let d = digits[i];
if(d === '0') continue;
if(i >= 1 && digits[i-1] === '0') {
retStr += numbers[0];
}
let unit = digits.length - i - 1;
let isTwoThousand = d === '2' && unit === 3;
retStr += (isTwoThousand ? alternateTwo : numbers[d]) + units[unit];
}
return retStr;
};
// 先以 8 位切,然后以 4位切
let fragment4 = fragmentFactory(4, '万', resolve4);
let fragment8 = fragmentFactory(8, '亿', fragment4);
// 要 京 兆 垓 都是没有问题的
// fragment 16 京, fragment 32 兆 一直写下去就行
return fragment8(String(n)) || numbers[0];
} |
function returnChineseNumber(num, chineseType) {
if (!num) return '';
var numArr = [num].toString().split('');
var _numConfig = '零一二三四五六七八九'.split('');
var _unitConfig = ' 十百千'.split('');
var _sizeConfig = ' 万亿兆'.split('');
if (chineseType) {
_numConfig = '零壹贰叁肆伍陆柒捌玖'.split('');
_unitConfig = ' 拾佰仟'.split('');
// _sizeConfig = ' 萬億兆'.split('');
}
var result = '';
for (var i=0,len=numArr.length; i<len; i++) {
var n = Number(numArr[len-i-1]);
var cn = _numConfig[n];
var unit = i%4 !== 0 ? _unitConfig[i%4] : '';
var size = i%4 === 0 && i !== 0 ? _sizeConfig[i/4] : '';
// 现在将返回 1001 => 一千零百零十一,不符合情况,则进行以下处理
if (cn === '零') unit = '';
if (cn === '零' && (result === '' || result.slice(0, 1) === '零')) cn = '';
result = cn + unit + size + result;
}
return result;
}
console.log(returnChineseNumber(123123123))
// 一亿二千三百一十二万三千一百二十三 |
returnChineseNumber(201001); |
toChineseNumeral('1110'); |
感谢,代码已更新。 |
不好意思,搞定了,泡妞去了。 |
|
function transformNumber(number) {
const mapping = {
100000000: '亿',
10000000: '千万',
1000000: '百万',
100000: '十万',
10000: '万',
1000: '千',
100: '百',
10: '十',
0: '零',
1: '一',
2: '二',
3: '三',
4: '四',
5: '五',
6: '六',
7: '七',
8: '八',
9: '九'
}
const keys = Object.keys(mapping).sort((a, b) => b - a);
let retStr = '', temp = number, tempStr;
for (let k of keys) {
tempStr = ~~(temp / k);
temp = temp % k;
if (tempStr) {
retStr += `${mapping[tempStr]}${mapping[k]}`;
} else if (mapping[k] === '十' && tempStr === 1) {
retStr += '一十'; // 特殊处理 10 读作 一十
} else if (!tempStr && retStr && retStr[retStr.length - 1] !== '零') {
retStr += '零';
} else if (temp < 10) {
if (temp !== 0) { // 特殊处理末尾 0
retStr += mapping[temp]
}
break; // 已到达个位数,退出循环
}
if (!temp) break;
}
console.log(retStr);
}
transformNumber(10101101) // 一千万零一十万零一千一百零一 |
/**
* @desc
*
* @使用场景
*
* @coder.yang2010@gmail.com
* @Date 2019/12/5
**/
var unit = ['', '十', '百', '千'];
var segmentUnit = ['', '万', '亿','兆'];
var number = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
function transfer(digits: number, unitIndex = 0) {
// let segment = digits % 10000;
// let result = digits / 10000;
let segmentResults = [];
let currentSegment;
let nextVal=digits;
do {
currentSegment = nextVal % 10000;
nextVal = Math.floor(nextVal / 10000);
if (currentSegment > 0) {
segmentResults.push((nextVal>0?"零":"")+
transferSegment(currentSegment, segmentUnit[unitIndex++]),
);
}
} while (nextVal > 0);
return segmentResults.reverse().join('');
}
function transferSegment(segment: number, segmentUnit: string): string {
let result = [];
let currentValue = segment;
let _unitIndex = 0;
let isLastZero= null;
do {
let current = currentValue % 10;
currentValue = Math.trunc(currentValue / 10);
let _unit = unit[_unitIndex++];
if (current !== 0) {
result.push( number[current] + _unit,
);
isLastZero = false;
} else {
if(isLastZero===false){
result.push(
"零",
);
}
isLastZero = true;
}
} while (currentValue > 0);
return result.reverse().join("") + segmentUnit;
}
console.log(transfer(1000));
console.log(transfer(1001));
console.log(transfer(1011));
console.log(transfer(1111));
console.log(transfer(9999));
console.log(transfer(19999));
console.log(transfer(1000999)); |
function translateNumber(num) {
var numStr = Math.round(num).toString().split('')
if (numStr.length > 12) {
throw '数字超过最大范围:千亿'
}
var digitChar = ['', '一', '二', '三', '四', '五', '六', '七', '八', '九']
var posChar = ['', '十', '百', '千', '万', '十', '百', '千', '亿', '十', '百', '千']
var zeroChar = '零'
var lastChar
var result = numStr.map((char, index) => {
var pos = numStr.length - 1 - index
var res = digitChar[char]
if (char === '0') {
if (lastChar && lastChar !== zeroChar) { // 避免重复的零
if (pos === 4 || pos === 8) { // 处理万和亿
res += posChar[pos]
} else {
res += zeroChar
}
}
} else {
res += posChar[pos]
}
lastChar = digitChar[char]
return res
})
result = result.filter(i => i) // 去除空白数组项
if (result.lastIndexOf(zeroChar) === result.length - 1) { // 删除最后的零
result.pop()
}
return result.join('')
}
console.log(translateNumber(5)) // 五
console.log(translateNumber(20)) // 二十
console.log(translateNumber(100)) // 一百
console.log(translateNumber(105)) // 一百零五
console.log(translateNumber(111)) // 一百一十一
console.log(translateNumber(256)) // 二百五十六
console.log(translateNumber(1024)) // 一千零二十四
console.log(translateNumber(10086)) // 一万零八十六
console.log(translateNumber(10001)) // 一万零一
console.log(translateNumber(101010)) // 一十万一千零一十
console.log(translateNumber(2050100)) // 二百零五万零一百
console.log(translateNumber(10101101)) // 一千零一十万一千一百零一
console.log(translateNumber(909090909001)) // 九千零九十亿九千零九十万九千零一 |
比我想的要难多了,思路是四个一组,为了与字典相匹配,倒序倒序再倒序。兼容性挺好的,支持 BigInt、小数、支持科学表示法的数字 // 支持 BigInt、小数、支持科学表示法的数字
const num2cn = (num) => {
const numDic = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']
const siteDic = ['千', '百', '十', '']
const groupDic = ['', '万', '亿', '兆', '京', '垓', '秭', '穰', '沟', '涧', '正', '载', '🐶']
const numStr = num.toLocaleString().replaceAll(',', '')
const [intArr, dicimalArr] = numStr.split('.').map(str => str.split(''))
const dicimalResult = dicimalArr ? '点' + dicimalArr.map(val => numDic[val]).join('') : ''
let groupInt = []
intArr.reverse().forEach((val, index) => {// 倒叙是为了 intArr 的数组下标与 groupDic 相对应
if (index % 4 === 0) groupInt.push(new Array(4).fill('0'))
groupInt[Math.floor(index / 4)][3 - index % 4] = val// 每一组也做了倒叙,与 siteDic 相对应
})
groupInt = groupInt
.map((arr, i) => {
// 每一组的值加上 siteDic 的单位
return arr.map((value, j) => {
if (value === '0') {
return numDic[value]
}
return numDic[value] + siteDic[j]
})
})
.reverse()// 组倒序
.reduce((str, arr, groupIndex, allArr) => {
const groupKey = groupDic[allArr.length - 1 - groupIndex]
return str + arr.reduce((before, current, currentIndex) => {
return before + current + (currentIndex === 3 ? groupKey : '')// 加上 groupDic 单位
}, '')
}, '')
// 去除各种多余的零
groupInt = groupInt.replace(/(?<=零)[零万亿兆京垓秭穰沟涧正载🐶]+|^零+|零+$/g, '') + dicimalResult
return groupInt
}
console.log(13, num2cn(13))
console.log(130000, num2cn(130000))
console.log(130000.4334, num2cn(13_0000.4334))
console.log(100_0000_0030, num2cn(100_0000_0030))
console.log(10_0000_0000_0000_0030n, num2cn(1_0000_0000_0000_0030n))
console.log(11_1111_1111_1111_1131n, num2cn(1_1111_1111_1111_1131n))
console.log(1010_1101, num2cn(1010_1101))
console.log(9090_9090_9001, num2cn(9090_9090_9001))
console.log(327_4823_9473_2947_1041_0412_3456_7080n, num2cn(327_4823_9473_2947_1041_0412_3456_7080n)) |
第114天 写一个把数字转成中文的方法,例如:101转成一百零一
The text was updated successfully, but these errors were encountered: