bar - iOS convierte grandes números a formatos más pequeños
status bar ios (20)
¿Cómo puedo convertir todos los números que tienen más de 3 dígitos en un número de 4 dígitos o menos?
Esto es exactamente lo que quiero decir:
10345 = 10.3k
10012 = 10k
123546 = 123.5k
4384324 = 4.3m
El redondeo no es del todo importante, pero una ventaja añadida.
He buscado en NSNumberFormatter pero no he encontrado la solución adecuada, y todavía tengo que encontrar una solución adecuada aquí en SO. ¡Cualquier ayuda es muy apreciada, gracias!
¡Aquí mi versión! Gracias a las respuestas anteriores. Los objetivos de esta versión son:
- Tenga un mejor control de umbral porque los detalles de números pequeños son más importantes que los detalles de números muy grandes
- Use la mayor cantidad posible de
NSNumberFormatter
para evitar problemas de ubicación (como coma en lugar de punto en francés) - Evite ".0" y redondear bien los números, que se pueden personalizar utilizando
NSNumberFormatterRoundingMode
Puede usar todas las maravillosas opciones de NSNumberFormatter
para satisfacer sus necesidades, consulte Referencia de clase de NSNumberFormatter
El código ( gist ):
extension Int {
func formatUsingAbbrevation () -> String {
let numFormatter = NSNumberFormatter()
typealias Abbrevation = (threshold:Double, divisor:Double, suffix:String)
let abbreviations:[Abbrevation] = [(0, 1, ""),
(1000.0, 1000.0, "K"),
(100_000.0, 1_000_000.0, "M"),
(100_000_000.0, 1_000_000_000.0, "B")]
// you can add more !
let startValue = Double (abs(self))
let abbreviation:Abbrevation = {
var prevAbbreviation = abbreviations[0]
for tmpAbbreviation in abbreviations {
if (startValue < tmpAbbreviation.threshold) {
break
}
prevAbbreviation = tmpAbbreviation
}
return prevAbbreviation
} ()
let value = Double(self) / abbreviation.divisor
numFormatter.positiveSuffix = abbreviation.suffix
numFormatter.negativeSuffix = abbreviation.suffix
numFormatter.allowsFloats = true
numFormatter.minimumIntegerDigits = 1
numFormatter.minimumFractionDigits = 0
numFormatter.maximumFractionDigits = 1
return numFormatter.stringFromNumber(NSNumber (double:value))!
}
}
let testValue:[Int] = [598, -999, 1000, -1284, 9940, 9980, 39900, 99880, 399880, 999898, 999999, 1456384, 12383474]
testValue.forEach() {
print ("Value : /($0) -> /($0.formatUsingAbbrevation ())")
}
Resultado:
Value : 598 -> 598
Value : -999 -> -999
Value : 1000 -> 1K
Value : -1284 -> -1.3K
Value : 9940 -> 9.9K
Value : 9980 -> 10K
Value : 39900 -> 39.9K
Value : 99880 -> 99.9K
Value : 399880 -> 0.4M
Value : 999898 -> 1M
Value : 999999 -> 1M
Value : 1456384 -> 1.5M
Value : 12383474 -> 12.4M
¿Por qué ustedes lo consiguen tan difícil?
Puede ser tan simple como esto:
-(NSString *)friendlyNumber:(long long)num{
NSString *stringNumber;
if (num < 1000) {
stringNumber = [NSString stringWithFormat:@"%lld", num];
}else if(num < 1000000){
float newNumber = floor(num / 100) / 10.0;
stringNumber = [NSString stringWithFormat:@"%.1fK", newNumber];
}else{
float newNumber = floor(num / 100000) / 10.0;
stringNumber = [NSString stringWithFormat:@"%.1fM", newNumber];
}
return stringNumber;
}
Aquí hay dos métodos que he encontrado para trabajar juntos para producir el efecto deseado. Esto también se redondeará automáticamente. Esto también especificará cuántos números totales serán visibles al pasar el int dec.
Además, en el método de flotación a cadena, puede cambiar @"%.1f"
a @"%.2f"
, @"%.3f"
, etc. para decirle cuántos decimales visibles se mostrarán después del punto decimal.
For Example:
52935 ---> 53K
52724 ---> 53.7K
-(NSString *)abbreviateNumber:(int)num withDecimal:(int)dec {
NSString *abbrevNum;
float number = (float)num;
NSArray *abbrev = @[@"K", @"M", @"B"];
for (int i = abbrev.count - 1; i >= 0; i--) {
// Convert array index to "1000", "1000000", etc
int size = pow(10,(i+1)*3);
if(size <= number) {
// Here, we multiply by decPlaces, round, and then divide by decPlaces.
// This gives us nice rounding to a particular decimal place.
number = round(number*dec/size)/dec;
NSString *numberString = [self floatToString:number];
// Add the letter for the abbreviation
abbrevNum = [NSString stringWithFormat:@"%@%@", numberString, [abbrev objectAtIndex:i]];
NSLog(@"%@", abbrevNum);
}
}
return abbrevNum;
}
- (NSString *) floatToString:(float) val {
NSString *ret = [NSString stringWithFormat:@"%.1f", val];
unichar c = [ret characterAtIndex:[ret length] - 1];
while (c == 48 || c == 46) { // 0 or .
ret = [ret substringToIndex:[ret length] - 1];
c = [ret characterAtIndex:[ret length] - 1];
}
return ret;
}
Espero que esto ayude a alguien más que lo necesite!
Aquí hay una versión actualizada de respuesta de que funciona con Swift 4
func suffixNumber(number: NSNumber) -> String {
var num:Double = number.doubleValue
let sign = ((num < 0) ? "-" : "" )
num = fabs(num)
if (num < 1000.0) {
return "/(sign)/(num)"
}
let exp: Int = Int(log10(num) / 3.0)
let units: [String] = ["K","M","G","T","P","E"]
let roundedNum: Double = round(10 * num / pow(1000.0,Double(exp))) / 10
return "/(sign)/(roundedNum)/(units[exp-1])";
}
Después de probar un par de estas soluciones, Luca laco parece tenerlo más cerca, pero he hecho algunas modificaciones a su método para tener más control sobre cuántos dígitos aparecerán (es decir, si desea que 120.3K sean más cortos, puede limitarlo a 120K). Además, he agregado un paso adicional que garantiza que un número como 999,999 no aparezca como 1000.0K, en lugar de 1.0M.
/*
With "onlyShowDecimalPlaceForNumbersUnder" = 10:
Original number: 598 - Result: 598
Original number: 1000 - Result: 1.0K
Original number: 1284 - Result: 1.3K
Original number: 9980 - Result: 10K
Original number: 39900 - Result: 40K
Original number: 99880 - Result: 100K
Original number: 999898 - Result: 1.0M
Original number: 999999 - Result: 1.0M
Original number: 1456384 - Result: 1.5M
Original number: 12383474 - Result: 12M
*/
- (NSString *)suffixNumber:(NSNumber *)number
{
if (!number)
return @"";
long long num = [number longLongValue];
if (num < 1000)
return [NSString stringWithFormat:@"%lld",num];
int exp = (int) (log(num) / log(1000));
NSArray * units = @[@"K",@"M",@"G",@"T",@"P",@"E"];
int onlyShowDecimalPlaceForNumbersUnder = 10; // Either 10, 100, or 1000 (i.e. 10 means 12.2K would change to 12K, 100 means 120.3K would change to 120K, 1000 means 120.3K stays as is)
NSString *roundedNumStr = [NSString stringWithFormat:@"%.1f", (num / pow(1000, exp))];
int roundedNum = [roundedNumStr integerValue];
if (roundedNum >= onlyShowDecimalPlaceForNumbersUnder) {
roundedNumStr = [NSString stringWithFormat:@"%.0f", (num / pow(1000, exp))];
roundedNum = [roundedNumStr integerValue];
}
if (roundedNum >= 1000) { // This fixes a number like 999,999 from displaying as 1000K by changing it to 1.0M
exp++;
roundedNumStr = [NSString stringWithFormat:@"%.1f", (num / pow(1000, exp))];
}
NSString *result = [NSString stringWithFormat:@"%@%@", roundedNumStr, [units objectAtIndex:(exp-1)]];
NSLog(@"Original number: %@ - Result: %@", number, result);
return result;
}
El siguiente método maneja los números positivos y negativos a diferencia de la mayoría de las soluciones aquí.
Incluso funciona para la moneda también.
BOOL isCurrency = YES; // Make it YES / NO depending upon weather your input value belongs to a revenue figure or a normal value.
double value = XXX ; // where ''XXX'' is your input value
NSString *formattedValue = @"";
int decimalPlaces = 1; // number of decimal places (precision) that you want.
float multiplier;
// Enumerate number abbreviations
NSArray *abbrevations = @[@"", @"k", @"m", @"b", @"t" ];
// Go through the array backwards, so we do the largest first
int index;
for (index = abbrevations.count-1; index >= 0; index--) {
multiplier = pow(10, decimalPlaces);
// Convert array index to "1000", "1000000", etc
double size = pow(10, index*3);
// If the number is bigger or equal do the abbreviation
if(size <= fabs(round(value)))
{
// Here, we multiply by multiplier, round, and then divide by multiplier.
// This gives us nice rounding to a particular decimal place.
value = round(value * multiplier / size) / multiplier;
// We are done... stop
break;
}
}
if (index<0)
{
// Note: - To handle special case where x is our input number, -0.5 > x < 0.5
value = 0;
index++;
}
NSString *stringFormat = nil;
// Add the letter for the abbreviation
if (isCurrency)
{
if (value >=0)
{
stringFormat = [NSString stringWithFormat:@"$%%.%0df%@", decimalPlaces, abbrevations[index]];
}
else
{
// Note: - To take care of extra logic where ''$'' symbol comes after ''-'' symbol for negative currency.
stringFormat = [NSString stringWithFormat:@"-$%%.%df%@", decimalPlaces, abbrevations[index]];
value = -value;
}
}
else
{
stringFormat = [NSString stringWithFormat:@"%%.%0df%@", decimalPlaces, abbrevations[index]];
}
formattedValue = [NSString stringWithFormat:stringFormat, value];
La salida es la siguiente
In Currency mode
''999'' ---- ''$999.0''
''999.9'' ---- ''$1.0k''
''999999.9'' ---- ''$1.0m''
''-1000.1'' ---- ''-$1.0k''
''-0.9'' ---- ''-$0.9''
In Number mode
''999'' ---- ''999.0''
''999.9'' ---- ''1.0k''
''1'' ---- ''1.0''
''9999'' ---- ''10.0k''
''99999.89999999999'' ---- ''100.0k''
''999999.9'' ---- ''1.0m''
''-1'' ---- ''-1.0''
''-1000.1'' ---- ''-1.0k''
''5109999'' ---- ''5.1m''
''-5109999'' ---- ''-5.1m''
''999999999.9'' ---- ''1.0b''
''0.1'' ---- ''0.0''
''0'' ---- ''0.0''
''-0.1'' ---- ''0.0''
''-0.9'' ---- ''-0.9''
He creado el método anterior basado en la inspiración original de @Kyle Begeman del enlace compartido por @Pandiyan Cool. Gracias a @Jeff B por el código inicial en Javascript del siguiente enlace. ¿Hay una manera de redondear los números en un formato fácil de leer? (por ejemplo, $ 1.1k)
Me encontré con un problema similar al intentar formatear los valores del eje y en los Gráficos de Shinobi. Se requería usar un NSNumberFormatter, por lo que finalmente se me ocurrió esto
NSNumberFormatter *numFormatter = [[NSNumberFormatter alloc] init];
[numFormatter setPositiveFormat:@"0M"];
[numFormatter setMultiplier:[NSNumber numberWithDouble:0.000001]];
Para obtener un valor formateado
NSString *formattedNumber = [numFormatter stringFromNumber:[NSNumber numberWithInteger:4000000]]; //@"4M"
Esta solución no incluye el redondeo, pero si usted (o cualquier otra persona) necesita algo simple, esto podría funcionar. Si necesita por mil en lugar de por millón, cambia la "M" a una "K" en el método setPostiveFormat, y cambia el valor de NSNumber en el multiplicador a 0.001.
Puede utilizar esta función simple, la idea es fácil de entender
-(NSString*) suffixNumber:(NSNumber*)number
double value = [number doubleValue];
NSUInteger index = 0;
NSArray *suffixArray = @[@"", @"K", @"M", @"B", @"T", @"P", @"E"];
while ((value/1000) >= 1){
value = value/1000;
index++;
}
//3 line of code below for round doubles to 1 digit
NSNumberFormatter *fmt = [[NSNumberFormatter alloc] init];
[fmt setMaximumFractionDigits:1];
NSString *valueWith1Digit = [fmt stringFromNumber:[NSNumber numberWithFloat:value]];
NSString *svalue = [NSString stringWithFormat:@"%@%@",valueWith1Digit, [suffixArray objectAtIndex:index]];
return svalue;
}
Prueba
NSLog(@"%@",[self suffixNumber:@100]); // 100
NSLog(@"%@",[self suffixNumber:@1000]); // 1K
NSLog(@"%@",[self suffixNumber:@10345]); // 10.3K
NSLog(@"%@",[self suffixNumber:@10012]); // 10K
NSLog(@"%@",[self suffixNumber:@123456]); // 123.5K
NSLog(@"%@",[self suffixNumber:@4384324]); // 4.4M
NSLog(@"%@",[self suffixNumber:@10000000]) // 10M
Respuesta actualizada para la conversión rápida
extension Int {
func abbreviateNumber() -> String {
func floatToString(val: Float) -> String {
var ret: NSString = NSString(format: "%.1f", val)
let c = ret.characterAtIndex(ret.length - 1)
if c == 46 {
ret = ret.substringToIndex(ret.length - 1)
}
return ret as String
}
var abbrevNum = ""
var num: Float = Float(self)
if num >= 1000 {
var abbrev = ["K","M","B"]
for var i = abbrev.count-1; i >= 0; i-- {
let sizeInt = pow(Double(10), Double((i+1)*3))
let size = Float(sizeInt)
if size <= num {
num = num/size
var numStr: String = floatToString(num)
if numStr.hasSuffix(".0") {
let startIndex = numStr.startIndex.advancedBy(0)
let endIndex = numStr.endIndex.advancedBy(-2)
let range = startIndex..<endIndex
numStr = numStr.substringWithRange( range )
}
let suffix = abbrev[i]
abbrevNum = numStr+suffix
}
}
} else {
abbrevNum = "/(num)"
let startIndex = abbrevNum.startIndex.advancedBy(0)
let endIndex = abbrevNum.endIndex.advancedBy(-2)
let range = startIndex..<endIndex
abbrevNum = abbrevNum.substringWithRange( range )
}
return abbrevNum
}
}
Sé que ya hay muchas respuestas y formas diferentes, pero así es como lo resolví con un enfoque más funcional:
extension Int {
var abbreviated: String {
let abbrev = "KMBTPE"
return abbrev.characters
.enumerated()
.reversed()
.reduce(nil as String?) { accum, tuple in
let factor = Double(self) / pow(10, Double(tuple.0 + 1) * 3)
let format = (factor - floor(factor) == 0 ? "%.0f%@" : "%.1f%@")
return accum ?? (factor >= 1 ? String(format: format, factor, String(tuple.1)) : nil)
} ?? String(self)
}
}
Si está interesado en formatear el número de bytes, este artículo de Mattt Thompson muestra cómo usar el NSByteCountFormatter iOS / OSX
También hay formateadores incorporados para energy , mass , length y un montón de otros.
El quid de esto es que para la mayoría de las unidades comunes no es necesario escribir ningún código personalizado, ya que Apple ya le proporcionó el trabajo tedioso. Verifique su referencia en línea para el formateador NS [SomeUnit], por ejemplo, NSDateIntervalFormatter
, NSDateIntervalFormatter
o NSDateFormatter
, etc.
Swift 2.2 como doble extensión:
extension Double {
var suffixNumber : String {
get {
var num = self
let sign = ((num < 0) ? "-" : "" )
num = fabs(num)
if (num < 1000.0){
return "/(sign)/(num)"
}
let exp:Int = Int(log10(num) / 3.0 )
let units:[String] = ["K","M","G","T","P","E"]
let roundedNum = round(10 * num / pow(1000.0,Double(exp))) / 10
return "/(sign)/(roundedNum)/(units[exp-1])"
}
}
}
Tuve el mismo problema y terminé usando el enfoque de Kyle, pero desafortunadamente se rompe cuando se usan números como 120000 , mostrando 12k en lugar de 120K y necesitaba mostrar números pequeños como: 1.1K en lugar de redondear a 1K.
Así que aquí está mi edición de la idea original de Kyle:
Results:
[self abbreviateNumber:987] ---> 987
[self abbreviateNumber:1200] ---> 1.2K
[self abbreviateNumber:12000] ----> 12K
[self abbreviateNumber:120000] ----> 120K
[self abbreviateNumber:1200000] ---> 1.2M
[self abbreviateNumber:1340] ---> 1.3K
[self abbreviateNumber:132456] ----> 132.5K
-(NSString *)abbreviateNumber:(int)num {
NSString *abbrevNum;
float number = (float)num;
//Prevent numbers smaller than 1000 to return NULL
if (num >= 1000) {
NSArray *abbrev = @[@"K", @"M", @"B"];
for (int i = abbrev.count - 1; i >= 0; i--) {
// Convert array index to "1000", "1000000", etc
int size = pow(10,(i+1)*3);
if(size <= number) {
// Removed the round and dec to make sure small numbers are included like: 1.1K instead of 1K
number = number/size;
NSString *numberString = [self floatToString:number];
// Add the letter for the abbreviation
abbrevNum = [NSString stringWithFormat:@"%@%@", numberString, [abbrev objectAtIndex:i]];
}
}
} else {
// Numbers like: 999 returns 999 instead of NULL
abbrevNum = [NSString stringWithFormat:@"%d", (int)number];
}
return abbrevNum;
}
- (NSString *) floatToString:(float) val {
NSString *ret = [NSString stringWithFormat:@"%.1f", val];
unichar c = [ret characterAtIndex:[ret length] - 1];
while (c == 48) { // 0
ret = [ret substringToIndex:[ret length] - 1];
c = [ret characterAtIndex:[ret length] - 1];
//After finding the "." we know that everything left is the decimal number, so get a substring excluding the "."
if(c == 46) { // .
ret = [ret substringToIndex:[ret length] - 1];
}
}
return ret;
}
Espero que esto les pueda ayudar chicos.
Usé la respuesta de gbitaudeau para hacer esta categoría de Objective-C de NSNumberFormatter, que uso en nuestro proyecto ( Vero.co ). La instancia de NSNumberFormatter aquí creada solo una vez para todo el proyecto.
@implementation NSNumberFormatter (Abbreviation)
+ (NSString*) abbreviatedStringFromNumber:(NSNumber*) number
{
static dispatch_once_t pred;
static NSNumberFormatter* __abbrFormatter = nil;
static NSArray<NSDictionary*> * __abbreviations = nil;
dispatch_once(&pred, ^{
__abbrFormatter = [[NSNumberFormatter alloc] init];
__abbrFormatter.numberStyle = NSNumberFormatterDecimalStyle;
__abbrFormatter.usesGroupingSeparator = YES;
__abbrFormatter.allowsFloats = YES;
__abbrFormatter.minimumIntegerDigits = 1;
__abbrFormatter.minimumFractionDigits = 0;
__abbrFormatter.maximumFractionDigits = 2;
__abbreviations = @[@{@"threshold":@(0.0), @"divisor":@(1.0), @"suffix":@""},
@{@"threshold":@(1000.0), @"divisor":@(1000.0), @"suffix":@"K"},
@{@"threshold":@(1000000.0), @"divisor":@(1000000.0), @"suffix":@"M"}];
});
double startValue = ABS([number doubleValue]);
NSDictionary* abbreviation = __abbreviations[0];
for (NSDictionary* tmpAbbr in __abbreviations)
{
if (startValue < [tmpAbbr[@"threshold"] doubleValue])
{
break;
}
abbreviation = tmpAbbr;
}
double value = [number doubleValue] / [abbreviation[@"divisor"] doubleValue];
[__abbrFormatter setLocale:[NSLocale currentLocale]]; //user might change locale while the app is sleeping
[__abbrFormatter setPositiveSuffix:abbreviation[@"suffix"]];
[__abbrFormatter setNegativeSuffix:abbreviation[@"suffix"]];
return [__abbrFormatter stringFromNumber:@(value)];
}
@end
Ahora puedes llamarlo así
[NSNumberFormatter abbreviatedStringFromNumber:@(N)];
Versión Swift 4.0 de la respuesta de Phan Van Linh
private static let suffix = ["", "K", "M", "B", "T", "P", "E"]
public static func formatNumber(_ number: Double) -> String{
var index = 0
var value = number
while((value / 1000) >= 1){
value = value / 1000
index += 1
}
return String(format: "%.1f%@", value, suffix[index])
}
Versión rápida
Traducción directa de la versión de Objective-C
func abbreviateNumber(num: NSNumber) -> NSString {
var ret: NSString = ""
let abbrve: [String] = ["K", "M", "B"]
var floatNum = num.floatValue
if floatNum > 1000 {
for i in 0..<abbrve.count {
let size = pow(10.0, (Float(i) + 1.0) * 3.0)
println("/(size) /(floatNum)")
if (size <= floatNum) {
let num = floatNum / size
let str = floatToString(num)
ret = NSString(format: "%@%@", str, abbrve[i])
}
}
} else {
ret = NSString(format: "%d", Int(floatNum))
}
return ret
}
func floatToString(val: Float) -> NSString {
var ret = NSString(format: "%.1f", val)
var c = ret.characterAtIndex(ret.length - 1)
while c == 48 {
ret = ret.substringToIndex(ret.length - 1)
c = ret.characterAtIndex(ret.length - 1)
if (c == 46) {
ret = ret.substringToIndex(ret.length - 1)
}
}
return ret
}
abbreviateNumber(123)
abbreviateNumber(12503)
abbreviateNumber(12934203)
abbreviateNumber(12234200003)
abbreviateNumber(92234203)
abbreviateNumber(9223.3)
Doble extension
Swift-4 Doble extension
: funciona bien en todos los casos.
extension Double {
// Formatting double value to k and M
// 1000 = 1k
// 1100 = 1.1k
// 15000 = 15k
// 115000 = 115k
// 1000000 = 1m
func formatPoints() -> String{
let thousandNum = self/1000
let millionNum = self/1000000
if self >= 1000 && self < 1000000{
if(floor(thousandNum) == thousandNum){
return ("/(Int(thousandNum))k").replacingOccurrences(of: ".0", with: "")
}
return("/(thousandNum.roundTo(places: 1))k").replacingOccurrences(of: ".0", with: "")
}
if self > 1000000{
if(floor(millionNum) == millionNum){
return("/(Int(thousandNum))k").replacingOccurrences(of: ".0", with: "")
}
return ("/(millionNum.roundTo(places: 1))M").replacingOccurrences(of: ".0", with: "")
}
else{
if(floor(self) == self){
return ("/(Int(self))")
}
return ("/(self)")
}
}
/// Returns rounded value for passed places
///
/// - parameter places: Pass number of digit for rounded value off after decimal
///
/// - returns: Returns rounded value with passed places
func roundTo(places:Int) -> Double {
let divisor = pow(10.0, Double(places))
return (self * divisor).rounded() / divisor
}
}
La respuesta de Flávio J Vieira Caetano se convirtió a Swift 3.0
extension Int {
var abbreviated: String {
let abbrev = "KMBTPE"
return abbrev.characters.enumerated().reversed().reduce(nil as String?) { accum, tuple in
let factor = Double(self) / pow(10, Double(tuple.0 + 1) * 3)
let format = (factor.truncatingRemainder(dividingBy: 1) == 0 ? "%.0f%@" : "%.1f%@")
return accum ?? (factor > 1 ? String(format: format, factor, String(tuple.1)) : nil)
} ?? String(self)
}
}
extension Int {
func abbreviateNumber() -> String {
func floatToString(val: Float) -> String {
var ret: NSString = NSString(format: "%.1f", val)
var c = ret.characterAtIndex(ret.length - 1)
if c == 46 {
ret = ret.substringToIndex(ret.length - 1)
}
return ret as String
}
var abbrevNum = ""
var num: Float = Float(self)
if num >= 1000 {
var abbrev = ["K","M","B"]
for var i = abbrev.count-1; i >= 0; i-- {
var sizeInt = pow(Double(10), Double((i+1)*3))
var size = Float(sizeInt)
if size <= num {
num = num/size
var numStr: String = floatToString(num)
if numStr.hasSuffix(".0") {
numStr = numStr.substringToIndex(advance(numStr.startIndex,count(numStr)-2))
}
var suffix = abbrev[i]
abbrevNum = numStr+suffix
}
}
} else {
abbrevNum = "/(num)"
if abbrevNum.hasSuffix(".0") {
abbrevNum = abbrevNum.substringToIndex(advance(abbrevNum.startIndex, count(abbrevNum)-2))
}
}
return abbrevNum
}
}
-(NSString*) suffixNumber:(NSNumber*)number
{
if (!number)
return @"";
long long num = [number longLongValue];
int s = ( (num < 0) ? -1 : (num > 0) ? 1 : 0 );
NSString* sign = (s == -1 ? @"-" : @"" );
num = llabs(num);
if (num < 1000)
return [NSString stringWithFormat:@"%@%lld",sign,num];
int exp = (int) (log10l(num) / 3.f); //log10l(1000));
NSArray* units = @[@"K",@"M",@"G",@"T",@"P",@"E"];
return [NSString stringWithFormat:@"%@%.1f%@",sign, (num / pow(1000, exp)), [units objectAtIndex:(exp-1)]];
}
uso de la muestra
NSLog(@"%@",[self suffixNumber:@100]); // 100
NSLog(@"%@",[self suffixNumber:@1000]); // 1.0K
NSLog(@"%@",[self suffixNumber:@1500]); // 1.5K
NSLog(@"%@",[self suffixNumber:@24000]); // 24.0K
NSLog(@"%@",[self suffixNumber:@99900]); // 99.9K
NSLog(@"%@",[self suffixNumber:@99999]); // 100.0K
NSLog(@"%@",[self suffixNumber:@109999]); // 110.0K
NSLog(@"%@",[self suffixNumber:@5109999]); // 5.1M
NSLog(@"%@",[self suffixNumber:@8465445223]); // 8.5G
NSLog(@"%@",[self suffixNumber:[NSNumber numberWithInt:-120]]); // -120
NSLog(@"%@",[self suffixNumber:[NSNumber numberWithLong:-5000000]]); // -5.0M
NSLog(@"%@",[self suffixNumber:[NSNumber numberWithDouble:-3.5f]]); // -3
NSLog(@"%@",[self suffixNumber:[NSNumber numberWithDouble:-4000.63f]]); // -4.0K
[ Actualización ]
Versión Swift a continuación:
func suffixNumber(number:NSNumber) -> NSString {
var num:Double = number.doubleValue;
let sign = ((num < 0) ? "-" : "" );
num = fabs(num);
if (num < 1000.0){
return "/(sign)/(num)";
}
let exp:Int = Int(log10(num) / 3.0 ); //log10(1000));
let units:[String] = ["K","M","G","T","P","E"];
let roundedNum:Double = round(10 * num / pow(1000.0,Double(exp))) / 10;
return "/(sign)/(roundedNum)/(units[exp-1])";
}
uso de la muestra
print(self.suffixNumber(NSNumber(long: 100))); // 100.0
print(self.suffixNumber(NSNumber(long: 1000))); // 1.0K
print(self.suffixNumber(NSNumber(long: 1500))); // 1.5K
print(self.suffixNumber(NSNumber(long: 24000))); // 24.0K
print(self.suffixNumber(NSNumber(longLong: 99900))); // 99.9K
print(self.suffixNumber(NSNumber(longLong: 99999))); // 100.0K
print(self.suffixNumber(NSNumber(longLong: 109999))); // 110.0K
print(self.suffixNumber(NSNumber(longLong: 5109999))); // 5.1K
print(self.suffixNumber(NSNumber(longLong: 8465445223))); // 8.5G
print(self.suffixNumber(NSNumber(long: -120))); // -120.0
print(self.suffixNumber(NSNumber(longLong: -5000000))); // -5.0M
print(self.suffixNumber(NSNumber(float: -3.5))); // -3.5
print(self.suffixNumber(NSNumber(float: -4000.63))); // -4.0K
Espero eso ayude