How do I get localised short scale compact number formats?

Hello all,

I've been investigating and trying to code a compact number format otherwise known as a short scale formatter or a humanizing big numbers into smaller ones in Swift.

I've been playing around with code I found on Stackoverflow; and in some instances they either rely on an array of keys/symbols without any boundary checking, or aren't complete, or aren't consistent in their formatting or results; or aren't localisable to different languages.

In my research, I found that Twitter, Javascript libraries, etc use/refer to the Unicode standard,

Unicode ICU 67.1 at:
https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/numberformatter_8h.html

And on the Mozilla site, the standard Intl.number format at:

Shows a way to get short formats:

console.log(new Intl.NumberFormat('en-GB', { notation: "compact" , compactDisplay: "short" }).format(987654321));

And, on the twitter github at:
https://github.com/twitter/twitter-cldr-js/blob/master/lib/assets/javascripts/twitter_cldr/es-US.js

They split up the short scale formats by locales and I think they use a pattern technique, as referred to by the Unicode standard at:

http://cldr.unicode.org/translation/numbers-currency/number-patterns#TOC-Compact-decimal-formatting-Short-Numbers

Given this, rather than trying to recode the wheel I was wondering whether it is possible to use the Unicode standard to short scale numbers?

I've noticed that In the open-source code for Apple Swift on Github there is indeed a reference to compactdecimalformat.h at:

But I don't know how to use it.

I'm wondering does anybody know how to call or use compactdecimalformat.h from the darwin library?

Alternatively, if there already is a framework or library that handles this kind of formatting; please let me know.

I did post a question on Stackoverflow about this, but perhaps the decided Swift forum can help or assist?

Not sure if this is what you want:

import Foundation

let nf = NumberFormatter()
nf.usesGroupingSeparator = true

nf.locale = Locale.init(identifier: "en_GB")
nf.numberStyle = .decimal; nf.string(from: 1234567).map { print($0) }
nf.numberStyle = .spellOut; nf.string(from: 1234567).map { print($0) }
nf.numberStyle = .currencyISOCode; nf.string(from: 1234567).map { print($0) }
print("--")
nf.locale = Locale.init(identifier: "sv_SE")
nf.numberStyle = .decimal; nf.string(from: 1234567).map { print($0) }
nf.numberStyle = .spellOut; nf.string(from: 1234567).map { print($0) }
nf.numberStyle = .currencyISOCode; nf.string(from: 1234567).map { print($0) }

will print:

1,234,567
one million two hundred thirty-four thousand five hundred sixty-seven
GBP 1,234,567.00
--
1 234 567
en miljon två­hundra­trettio­fyra­tusen fem­hundra­sextio­sju
1 234 567,00 SEK

I'm after short shale format, so instead of 1,234,567.00 GBP you'd get $1.23M; but thanks for the assitance and reply -- it should return/display the correct symbol for that locale.

I wonder if nf.string(from: 1234567).map { print($0) } could be used to filter out all the extra numbers after a pattern to display the scale. But as far as I know there isn't a short scale symbol to put in the suffix.

This looks relevant:

2 Likes

Hope it gets approved. Certainly if it gets implemented I can see it being used for Apple watch or other small UIs

Unlikely, unless Foundation gains the same capability on Apple platforms. Even then it may take up to a year for it to filter over to the open source side of things.

Okay, understood. I think I'll just use the one I have for now and not worry so much about localising it until its an issue