자바 스크립트에서 긴 숫자를 축약 된 문자열로 변환합니다.
JavaScript에서 주어진 [edit : 양의 정수 ] 숫자 (1000 억 미만)를 3 글자 약어 로 변환하는 함수를 작성하는 방법은 무엇 입니까? 0-9 및 az / AZ는 문자로 계산되지만 점은 (많은 비례 글꼴에서 너무 작기 때문에) 문자 제한 측면에서 무시되지 않을까요?
이 질문은 이 유용한 스레드 와 관련 이 있지만 동일하지 않습니다. 예를 들어, 그 함수가 예를 들어 "123456-> 1.23k"( "123.5k"는 5 글자)로 바뀌면 "123456-> 0.1m"( "0 [.] 1m"은 3 글자 ). 예를 들어, 이것은 원하는 함수의 출력 (왼쪽 원본, 오른쪽 이상적인 반환 값)입니다.
0 "0"
12 "12"
123 "123"
1234 "1.2k"
12345 "12k"
123456 "0.1m"
1234567 "1.2m"
12345678 "12m"
123456789 "0.1b"
1234567899 "1.2b"
12345678999 "12b"
감사!
업데이트 : 감사합니다! 다음 수정 사항이있을 때 요구 사항에 따라 답변이 제공되고 작동합니다.
function abbreviateNumber(value) {
var newValue = value;
if (value >= 1000) {
var suffixes = ["", "k", "m", "b","t"];
var suffixNum = Math.floor( (""+value).length/3 );
var shortValue = '';
for (var precision = 2; precision >= 1; precision--) {
shortValue = parseFloat( (suffixNum != 0 ? (value / Math.pow(1000,suffixNum) ) : value).toPrecision(precision));
var dotLessShortValue = (shortValue + '').replace(/[^a-zA-Z 0-9]+/g,'');
if (dotLessShortValue.length <= 2) { break; }
}
if (shortValue % 1 != 0) shortValue = shortValue.toFixed(1);
newValue = shortValue+suffixes[suffixNum];
}
return newValue;
}
나는 ninjagecko의 솔루션이 당신이 원하는 표준을 따르지 않는다고 생각합니다. 다음 기능은 다음을 수행합니다.
function intToString (value) {
var suffixes = ["", "k", "m", "b","t"];
var suffixNum = Math.floor((""+value).length/3);
var shortValue = parseFloat((suffixNum != 0 ? (value / Math.pow(1000,suffixNum)) : value).toPrecision(2));
if (shortValue % 1 != 0) {
var shortNum = shortValue.toFixed(1);
}
return shortValue+suffixes[suffixNum];
}
99 조보다 큰 값의 경우 문자가 추가되지 않으며 '접미사'배열에 추가하여 쉽게 수정할 수 있습니다.
Philipp의 편집은 다음과 같습니다. 다음 변경 사항으로 모든 요구 사항에 완벽하게 맞습니다!
function abbreviateNumber(value) {
var newValue = value;
if (value >= 1000) {
var suffixes = ["", "k", "m", "b","t"];
var suffixNum = Math.floor( (""+value).length/3 );
var shortValue = '';
for (var precision = 2; precision >= 1; precision--) {
shortValue = parseFloat( (suffixNum != 0 ? (value / Math.pow(1000,suffixNum) ) : value).toPrecision(precision));
var dotLessShortValue = (shortValue + '').replace(/[^a-zA-Z 0-9]+/g,'');
if (dotLessShortValue.length <= 2) { break; }
}
if (shortValue % 1 != 0) shortNum = shortValue.toFixed(1);
newValue = shortValue+suffixes[suffixNum];
}
return newValue;
}
이것은 매우 큰 값도 처리하며 좀 더 간결하고 효율적입니다.
abbreviate_number = function(num, fixed) {
if (num === null) { return null; } // terminate early
if (num === 0) { return '0'; } // terminate early
fixed = (!fixed || fixed < 0) ? 0 : fixed; // number of decimal places to show
var b = (num).toPrecision(2).split("e"), // get power
k = b.length === 1 ? 0 : Math.floor(Math.min(b[1].slice(1), 14) / 3), // floor at decimals, ceiling at trillions
c = k < 1 ? num.toFixed(0 + fixed) : (num / Math.pow(10, k * 3) ).toFixed(1 + fixed), // divide by power
d = c < 0 ? c : Math.abs(c), // enforce -0 is 0
e = d + ['', 'K', 'M', 'B', 'T'][k]; // append power
return e;
}
결과 :
for(var a='', i=0; i < 14; i++){
a += i;
console.log(a, abbreviate_number(parseInt(a),0));
console.log(-a, abbreviate_number(parseInt(-a),0));
}
0 0
-0 0
01 1
-1 -1
012 12
-12 -12
0123 123
-123 -123
01234 1.2K
-1234 -1.2K
012345 12.3K
-12345 -12.3K
0123456 123.5K
-123456 -123.5K
01234567 1.2M
-1234567 -1.2M
012345678 12.3M
-12345678 -12.3M
0123456789 123.5M
-123456789 -123.5M
012345678910 12.3B
-12345678910 -12.3B
01234567891011 1.2T
-1234567891011 -1.2T
0123456789101112 123.5T
-123456789101112 -123.5T
012345678910111213 12345.7T
-12345678910111212 -12345.7T
나는 당신 이이 숫자를 시도 할 수 없다고 생각합니다 .js /
1000을 1k로 변환하려면
console.log(numeral(1000).format('0a'));
123400을 123.4k로 변환하려면 이것을 시도하십시오.
console.log(numeral(123400).format('0.0a'));
여기에 상당히 우아한 솔루션이라고 생각합니다. 음수를 처리하지 않습니다 .
const COUNT_ABBRS = [ '', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' ];
function formatCount(count, withAbbr = false, decimals = 2) {
const i = 0 === count ? count : Math.floor(Math.log(count) / Math.log(1000));
let result = parseFloat((count / Math.pow(1000, i)).toFixed(decimals));
if(withAbbr) {
result += `${COUNT_ABBRS[i]}`;
}
return result;
}
예 :
formatCount(1000, true);
=> '1k'
formatCount(100, true);
=> '100'
formatCount(10000, true);
=> '10k'
formatCount(10241, true);
=> '10.24k'
formatCount(10241, true, 0);
=> '10k'
formatCount(10241, true, 1)
=> '10.2k'
formatCount(1024111, true, 1)
=> '1M'
formatCount(1024111, true, 2)
=> '1.02M'
https://stackoverflow.com/a/10600491/711085의 내 답변을 기반으로 , 귀하의 답변은 실제로 .substring(0,3)
다음 을 사용하여 구현하는 데 약간 더 짧습니다 .
function format(n) {
with (Math) {
var base = floor(log(abs(n))/log(1000));
var suffix = 'kmb'[base-1];
return suffix ? String(n/pow(1000,base)).substring(0,3)+suffix : ''+n;
}
}
(평소처럼, 당신이하는 일을 정확히 알지 못한다면 Math를 사용하지 마십시오. 할당 var pow=...
등은 미친 버그를 유발할 수 있습니다. 더 안전한 방법은 링크를 참조하십시오.)
> tests = [-1001, -1, 0, 1, 2.5, 999, 1234,
1234.5, 1000001, Math.pow(10,9), Math.pow(10,12)]
> tests.forEach(function(x){ console.log(x,format(x)) })
-1001 "-1.k"
-1 "-1"
0 "0"
1 "1"
2.5 "2.5"
999 "999"
1234 "1.2k"
1234.5 "1.2k"
1000001 "1.0m"
1000000000 "1b"
1000000000000 "1000000000000"
3 자에 대한 요구 사항이 엄격하다면 결과가 1 조를 초과하는 경우를 파악해야합니다. 그렇지 않으면 데이터가 손상 될 위험이 있으므로 매우 나쁩니다.
이 스레드에 대한 많은 답변은 Math
객체, 맵 객체, for 루프 등을 사용하여 다소 복잡해집니다 . 그러나 이러한 접근 방식은 실제로 디자인을 크게 개선하지는 않습니다. 더 많은 코드 라인, 더 많은 복잡성 및 더 많은 메모리 오버 헤드를 도입합니다. . 여러 접근 방식을 평가 한 후 수동 접근 방식이 가장 이해하기 쉽고 최고의 성능을 제공한다고 생각합니다.
const formatCash = n => {
if (n < 1e3) return n;
if (n >= 1e3 && n < 1e6) return +(n / 1e3).toFixed(1) + "K";
if (n >= 1e6 && n < 1e9) return +(n / 1e6).toFixed(1) + "M";
if (n >= 1e9 && n < 1e12) return +(n / 1e9).toFixed(1) + "B";
if (n >= 1e12) return +(n / 1e12).toFixed(1) + "T";
};
console.log(formatCash(1235000));
약간 놀아 본 후에이 접근 방식은 필수 기준을 충족하는 것 같습니다. @chuckator의 답변에서 영감을 얻었습니다.
function abbreviateNumber(value) {
if (value <= 1000) {
return value.toString();
}
const numDigits = (""+value).length;
const suffixIndex = Math.floor(numDigits / 3);
const normalisedValue = value / Math.pow(1000, suffixIndex);
let precision = 2;
if (normalisedValue < 1) {
precision = 1;
}
const suffixes = ["", "k", "m", "b","t"];
return normalisedValue.toPrecision(precision) + suffixes[suffixIndex];
}
Intl은 구현 된 국제화 된 동작을위한 자바 스크립트 표준 '패키지'입니다. Intl.NumberFormatter는 특히 지역화 된 숫자 포맷터입니다. 따라서이 코드는 실제로 로컬로 구성된 천 단위 및 소수 구분 기호를 따릅니다.
intlFormat(num) {
return new Intl.NumberFormat().format(Math.round(num*10)/10);
}
abbreviateNumber(value) {
let num = Math.floor(value);
if(num >= 1000000000)
return this.intlFormat(num/1000000000)+'B';
if(num >= 1000000)
return this.intlFormat(num/1000000)+'M';
if(num >= 1000)
return this.intlFormat(num/1000)+'k';
return this.intlFormat(num);
}
abbreviateNumber (999999999999) // 999B 제공
관련 질문 : 수천 (1k) 및 수백만 (1m)의 JavaScript에서 현지화 된 숫자를 축약합니다 .
암호
const SI_PREFIXES = [
{ value: 1, symbol: '' },
{ value: 1e3, symbol: 'k' },
{ value: 1e6, symbol: 'M' },
{ value: 1e9, symbol: 'G' },
{ value: 1e12, symbol: 'T' },
{ value: 1e15, symbol: 'P' },
{ value: 1e18, symbol: 'E' },
]
const abbreviateNumber = (number) => {
if (number === 0) return number
const tier = SI_PREFIXES.filter((n) => number >= n.value).pop()
const numberFixed = (number / tier.value).toFixed(1)
return `${numberFixed}${tier.symbol}`
}
abbreviateNumber(2000) // "2.0k"
abbreviateNumber(2500) // "2.5k"
abbreviateNumber(255555555) // "255.6M"
테스트:
import abbreviateNumber from './abbreviate-number'
test('abbreviateNumber', () => {
expect(abbreviateNumber(0)).toBe('0')
expect(abbreviateNumber(100)).toBe('100')
expect(abbreviateNumber(999)).toBe('999')
expect(abbreviateNumber(1000)).toBe('1.0k')
expect(abbreviateNumber(100000)).toBe('100.0k')
expect(abbreviateNumber(1000000)).toBe('1.0M')
expect(abbreviateNumber(1e6)).toBe('1.0M')
expect(abbreviateNumber(1e10)).toBe('10.0G')
expect(abbreviateNumber(1e13)).toBe('10.0T')
expect(abbreviateNumber(1e16)).toBe('10.0P')
expect(abbreviateNumber(1e19)).toBe('10.0E')
expect(abbreviateNumber(1500)).toBe('1.5k')
expect(abbreviateNumber(1555)).toBe('1.6k')
expect(abbreviateNumber(undefined)).toBe('0')
expect(abbreviateNumber(null)).toBe(null)
expect(abbreviateNumber('100')).toBe('100')
expect(abbreviateNumber('1000')).toBe('1.0k')
})
이 값을 얻기 위해이 함수를 사용하고 있습니다.
function Converter(number, fraction) {
let ranges = [
{ divider: 1, suffix: '' },
{ divider: 1e3, suffix: 'K' },
{ divider: 1e6, suffix: 'M' },
{ divider: 1e9, suffix: 'G' },
{ divider: 1e12, suffix: 'T' },
{ divider: 1e15, suffix: 'P' },
{ divider: 1e18, suffix: 'E' },
]
//find index based on number of zeros
let index = (Math.abs(number).toString().length / 3).toFixed(0)
return (number / ranges[index].divider).toFixed(fraction) + ranges[index].suffix
}
각 3 자리 숫자는 서로 다른 접미사를 가지고 있습니다. 이것이 제가 먼저 찾으려고하는 것입니다.
따라서 존재하는 경우 음수 기호를 제거 하고이 숫자에서 3 자리 수를 찾으십시오.
after that find appropriate suffix based on previous calculation added to divided number.
Converter(1500, 1)
Will return:
1.5K
I found better solution on SO here with fiddle running examples as @chucktator solution returns NaN in many cases. It worked perfectly fine for me.
function converse_number (labelValue) {
// Nine Zeroes for Billions
return Math.abs(Number(labelValue)) >= 1.0e+9
? Math.abs(Number(labelValue)) / 1.0e+9 + "B"
// Six Zeroes for Millions
: Math.abs(Number(labelValue)) >= 1.0e+6
? Math.abs(Number(labelValue)) / 1.0e+6 + "M"
// Three Zeroes for Thousands
: Math.abs(Number(labelValue)) >= 1.0e+3
? Math.abs(Number(labelValue)) / 1.0e+3 + "K"
: Math.abs(Number(labelValue));
}
alert(converse_number(100000000000));
@nimesaram
Your solution will not be desirable for the following case:
Input 50000
Output 50.0k
Following solution will work fine.
const convertNumberToShortString = (
number: number,
fraction: number
) => {
let newValue: string = number.toString();
if (number >= 1000) {
const ranges = [
{ divider: 1, suffix: '' },
{ divider: 1e3, suffix: 'k' },
{ divider: 1e6, suffix: 'm' },
{ divider: 1e9, suffix: 'b' },
{ divider: 1e12, suffix: 't' },
{ divider: 1e15, suffix: 'p' },
{ divider: 1e18, suffix: 'e' }
];
//find index based on number of zeros
const index = Math.floor(Math.abs(number).toString().length / 3);
let numString = (number / ranges[index].divider).toFixed(fraction);
numString =
parseInt(numString.substring(numString.indexOf('.') + 1)) === 0
? Math.floor(number / ranges[index].divider).toString()
: numString;
newValue = numString + ranges[index].suffix;
}
return newValue;
};
// Input 50000
// Output 50k
// Input 4500
// Output 4.5k
ReferenceURL : https://stackoverflow.com/questions/10599933/convert-long-number-into-abbreviated-string-in-javascript-with-a-special-shortn
'IT TIP' 카테고리의 다른 글
Func를 얻을 수 있습니까? (0) | 2020.12.25 |
---|---|
Java, BigDecimal의 소수 부분 만 추출 하시겠습니까? (0) | 2020.12.15 |
AttributeError : Python에서 속성을 설정할 수 없습니다. (0) | 2020.12.15 |
Karma 실행 단일 테스트 (0) | 2020.12.15 |
계산 된 속성과 클로저로 설정된 속성의 차이점 (0) | 2020.12.15 |