Thousands SeparatorLoading saved progress…

Thousands Separator

A thousands separator groups the digits of a number into runs of three — turning 1234567 into 1,234,567 — so a person can read the magnitude at a glance instead of counting zeros. You will write thousandsSeparator(value, options), which returns that grouped string. It has to group the integer part from the right, leave the decimals alone, keep a negative sign in front, and honor a custom separator and decimal mark. Browsers ship this in Intl.NumberFormat, but here you build the grouping by hand.

Signature

thousandsSeparator(
  value: number | string,
  options?: { separator?: string; decimal?: string }
): string
// separator defaults to ",", decimal defaults to "."

Examples

thousandsSeparator(1234567.89);  // '1,234,567.89'
thousandsSeparator(-1000);       // '-1,000'
thousandsSeparator(999);         // '999'
thousandsSeparator(1000000);     // '1,000,000'
thousandsSeparator(1234567, { separator: ' ' });                  // '1 234 567'
thousandsSeparator(1234567.89, { separator: '.', decimal: ',' }); // '1.234.567,89'
thousandsSeparator('1234567.89');                                 // '1,234,567.89'

Notes

  • Group from the right — the integer part splits into runs of three starting at the ones place, so the leftmost group may hold 1, 2, or 3 digits.
  • The fraction is never grouped — digits after the decimal point stay as a single run; only the integer part receives separators.
  • Sign stays in front — a negative value keeps its leading - before the first digit.
  • Number or stringvalue may be a JS number or a numeric string. A string lets a caller preserve exact decimals, such as a trailing zero that a number would drop.
  • Build it yourself — implement the grouping directly; do not delegate to Intl.NumberFormat or Number.prototype.toLocaleString.
  • Assume a normal magnitude — you can ignore values so large that JS prints them in exponential form (like 1e21), and you do not need to validate non-numeric junk.

FAQ

How do you group the integer part but not the decimals?
Split the number at its decimal point first, group only the integer substring into runs of three from the right, then re-attach the untouched fractional digits. The classic bug is running a grouping regex over the whole string, which also inserts separators inside the fraction.
How do you handle negative numbers?
Peel the leading minus sign off before grouping, group the remaining digits, then put the sign back in front. Feeding the minus straight into a digit grouper can drop or misplace it.
Why not just use Intl.NumberFormat or toLocaleString?
In production you should — new Intl.NumberFormat('en-US').format(n) handles grouping, locale separators, currency, and rounding. This exercise asks you to build the grouping by hand to show you understand the from-the-right chunking algorithm.
Loading editor…