2012-08-16 28 views
5

El usuario ingresará un valor en dólares como int, y me gustaría convertir el resultado en una cadena abreviada y formateada. Entonces, si el usuario ingresa 1700, la cadena diría "$ 1.7k". Si el usuario ingresa 32600000, la cadena dirá "$ 32.6m".Convertir int en cadena acortada y formateada

actualización

Aquí está el código que tengo hasta ahora. Parece estar funcionando para números ~ 10k. Simplemente agregaría más declaraciones if para números más grandes. Pero, ¿hay una manera más eficiente de hacer esto?

NSNumberFormatter *nformat = [[NSNumberFormatter alloc] init]; 
[nformat setFormatterBehavior:NSNumberFormatterBehavior10_4]; 
[nformat setCurrencySymbol:@"$"]; 
[nformat setNumberStyle:NSNumberFormatterCurrencyStyle]; 
double doubleValue = 10200; 
NSString *stringValue = nil; 
NSArray *abbrevations = [NSArray arrayWithObjects:@"k", @"m", @"b", @"t", nil] ; 

for (NSString *s in abbrevations) 
{ 

    doubleValue /= 1000.0 ; 

    if (doubleValue < 1000.0) 
    { 

     if ((long long)doubleValue % (long long) 100 == 0) { 
      [nformat setMaximumFractionDigits:0]; 
     } else {     
      [nformat setMaximumFractionDigits:2]; 
     } 

     stringValue = [NSString stringWithFormat: @"%@", [nformat stringFromNumber: [NSNumber numberWithDouble: doubleValue]] ]; 
     NSUInteger stringLen = [stringValue length]; 

     if ([stringValue hasSuffix:@".00"]) 
     {     
      // Remove suffix 
      stringValue = [stringValue substringWithRange: NSMakeRange(0, stringLen-3)];    
     } else if ([stringValue hasSuffix:@".0"]) { 

      // Remove suffix 
      stringValue = [stringValue substringWithRange: NSMakeRange(0, stringLen-2)]; 

     } else if ([stringValue hasSuffix:@"0"]) { 

      // Remove suffix 
      stringValue = [stringValue substringWithRange: NSMakeRange(0, stringLen-1)];   
     } 


     // Add the letter suffix at the end of it 
     stringValue = [stringValue stringByAppendingString: s]; 

     //stringValue = [NSString stringWithFormat: @"%@%@", [nformat stringFromNumber: [NSNumber numberWithDouble: doubleValue]] , s] ; 
     break ; 
    }  
} 

NSLog(@"Cash = %@", stringValue); 
+1

Usted puede hacerlo con un simple si ... else si ... – Selkie

+2

Estoy seguro de que ha intentado algo antes de hacer su pregunta, pero su código no funcionó. ¿Podría publicar su mejor esfuerzo? – dasblinkenlight

+1

¿Cómo obtendrías el punto decimal allí? es decir, convertir 1700 a 1.7. Creo que es con lo que estoy luchando. Divídalo antes de convertirlo a la cadena? – bmueller

Respuesta

14
unsigned long long value = 1700llu; 
//value = 32600001llu; 
//value = UINT64_MAX; 

NSUInteger index = 0; 
double dvalue = (double)value; 
//Updated to use correct SI Symbol (http://en.wikipedia.org/wiki/SI_prefix) 
NSArray *suffix = @[ @"", @"k", @"M", @"G", @"T", @"P", @"E" ]; 

while ((value/=1000) && ++index) dvalue /= 1000; 

NSString *svalue = [NSString stringWithFormat:@"$%.*f%@", 
        //Use boolean as 0 or 1 for precision 
        (int)(dvalue < 100.0 && ((unsigned)((dvalue - (unsigned)dvalue) * 10) > 0)), 
        dvalue, [suffix objectAtIndex:index]]; 
NSLog(@"Value: %@", svalue); 

ARC versión localizada

unsigned long long value = 1700llu; 
//value = 32600001llu; 
//value = UINT64_MAX; 

NSUInteger index = 0; 
double dvalue = (double)value; 
//Updated to use correct SI Symbol (http://en.wikipedia.org/wiki/SI_prefix) 
NSArray *suffix = @[ @"", @"k", @"M", @"G", @"T", @"P", @"E" ]; 

while ((value/=1000) && ++index) dvalue /= 1000; 

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; 
//Germany Example 
[formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"de-de"]]; 
//Set fractional digits to 0 or 1 
[formatter setMaximumFractionDigits:(int)(dvalue < 100.0 && ((unsigned)((dvalue - (unsigned)dvalue) * 10) > 0))]; 

NSString *svalue = [[formatter stringFromNumber:[NSNumber numberWithFloat:dvalue]] 
        stringByAppendingString:[suffix objectAtIndex:index]]; 

NSLog(@"Value: %@", svalue); 
+1

Guau, esto funciona perfectamente. ¡Usted, señor, es un caballero y un erudito! – bmueller

+0

Noté un problema: cuando el número especificado es, por ejemplo, '324,333', da salida a' 324.3k'. Este es uno de tantos caracteres para el espacio en el que estoy tratando de encajar. ¿Cómo podría deshacerme de todo después del decimal en este caso específico? – bmueller

+1

La estrella ('*') en '. * F' determina la cantidad de dígitos fraccionarios. Vea mi actualización al formato de cadena para asegurarse de que el valor sea <100 (3 caracteres). – Joe

7

Si quieres una cadena con un ancho de auto-ajustable que puede utilizar:

+(NSString*)numberWithShortcut:(NSNumber*)number 
{ 
    unsigned long long value = [number longLongValue]; 

    NSUInteger index = 0; 
    double dvalue = (double)value; 

    NSArray *suffix = @[ @"", @"K", @"M", @"B", @"T", @"P", @"E" ]; 

    while ((value /= 1000) && ++index) dvalue /= 1000; 

    NSString *svalue = [NSString stringWithFormat:@"%@%@",[NSNumber numberWithDouble:dvalue], [suffix objectAtIndex:index]]; 

    return svalue; 
} 
+0

Gracias. Buena versión limpia Me gusta. – mylogon