iOS convertit les grands nombres en plus petit format
Comment puis-je convertir tous les nombres qui sont plus de 3 chiffres en bas à 4 chiffres ou moins?
C'est exactement ce que je veux dire:
10345 = 10.3k
10012 = 10k
123546 = 123.5k
4384324 = 4.3m
Arrondissement n'est pas entièrement important, mais un plus.
j'ai regardé dans NSNumberFormatter mais n'ont pas trouvé la bonne solution, et je dois encore trouver une bonne solution ici sur SO. Toute aide est grandement appréciée, merci!
20 réponses
-(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)]];
}
exemple d'utilisation
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
[ mise à Jour ]
version Swift ci-dessous:
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])";
}
exemple d'utilisation
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
j'Espère que ça aide
j'ai eu le même problème et j'ai fini par utiliser L'approche de Kyle, mais malheureusement il se brise quand des nombres comme 120000 sont utilisés, montrant 12k au lieu de 120K et j'ai dû montrer de petits nombres comme: 1.1 K au lieu d'arrondir à 1K.
alors voici mon montage de L'idée originale 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;
}
J'espère que ça vous aidera.
voici ma version ! Merci aux réponses précédentes. Les buts de cette version est:
- ont un meilleur contrôle de seuil parce que les détails de petit nombre sont plus importants que les détails de très grand nombre
- utiliser autant que possible
NSNumberFormatter
pour éviter les problèmes d'emplacement (comma au lieu de point en français) - éviter".Les nombres de 0" et bien arrondis, qui peuvent être personnalisés en utilisant
NSNumberFormatterRoundingMode
Vous pouvez utiliser tous les merveilleux NSNumberFormatter
options pour répondre à vos besoins, consultez la section NSNumberFormatter Classe de Référence
le code ( 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 : \("151900920") -> \("151900920".formatUsingAbbrevation ())")
}
résultat:
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
Flávio J Vieira Caetano's answer converti en 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)
}
}
j'ai rencontré un problème similaire en essayant de formater les valeurs de L'axe des ordonnées Shinobi. Il a fallu utiliser un NSNumberFormatter, donc je suis finalement venu avec ce
NSNumberFormatter *numFormatter = [[NSNumberFormatter alloc] init];
[numFormatter setPositiveFormat:@"0M"];
[numFormatter setMultiplier:[NSNumber numberWithDouble:0.000001]];
pour obtenir une valeur formatée
NSString *formattedNumber = [numFormatter stringFromNumber:[NSNumber numberWithInteger:4000000]]; //@"4M"
cette solution n'a pas d'arrondissement inclus, mais si vous (ou quelqu'un d'autre) a juste besoin de quelque chose de simple, cela pourrait fonctionner. Si vous avez besoin par le millier au lieu de par le million, vous changez le "M" en un "K" dans le setPostiveFormat méthode, et changer la valeur du NN-Number dans le multiplicateur à 0.001 .
Voici deux méthodes que j'ai qui travaillent ensemble pour produire l'effet désiré. Cela se terminera aussi automatiquement. Cela précisera également combien de nombres totaux seront visibles en passant le déc int.
aussi, dans la méthode float to string, vous pouvez changer le @"%.1f"
en @"%.2f"
, @"%.3f"
, etc pour lui dire combien de décimales visibles montrer après le point décimal.
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;
}
Espérons que cette aide quelqu'un d'autre qui en a besoin!
après avoir essayé quelques-unes de ces solutions, Luca laco semble l'avoir le plus proche, mais j'ai fait quelques modifications à sa méthode afin d'avoir plus de contrôle sur le nombre de chiffres apparaîtra (i.e. si vous voulez 120.3 K pour être plus court, vous pouvez le limiter à 120K). En outre, j'ai ajouté une étape supplémentaire qui assure un nombre comme 999 999 n'apparaît pas comme 1000.0 K, plutôt 1.0 M.
/*
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;
}
je sais qu'il y a déjà beaucoup de réponses et de façons différentes, mais c'est comme ça que je l'ai résolu avec une approche plus fonctionnelle:
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)
}
}
version Swift
traduction directe de la version de L'objectif 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)
Vous pouvez utiliser cette fonction simple, l'idée est facile à comprendre
-(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;
}
essai
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
réponse mise à jour pour la conversion swift
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
}
}
Voici une version mise à jour de la réponse de Luca Iaco qui fonctionne avec 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])";
}
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
}
}
si vous êtes intéressé à formater le nombre d'octets, cet article de Mattt Thompson montre comment utiliser iOS / OSX builtin NSByteCountFormatter
Il ya aussi des formateursinstallés pour énergie , masse , longueur et un tas d'autres.
L'essentiel, c'est que pour la plupart des unités communes vous n'avez pas besoin d'écrire tout personnalisé code comme Apple a déjà fourni le travail fastidieux pour vous. Vérifiez leur référence en ligne pour NS [SomeUnit]Formatter, par exemple MKDistanceFormatter
, NSDateIntervalFormatter
ou NSDateFormatter
, etc...
j'ai utilisé la réponse de gbitaudeau pour faire cette catégorie D'Objectif C de NSNumberFormatter, que j'utilise dans notre projet ( Vero.co ). L'instance NSNumberFormatter n'a été créée qu'une seule fois pour l'ensemble du projet.
@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
vous pouvez maintenant l'appeler comme ça
[NSNumberFormatter abbreviatedStringFromNumber:@(N)];
Swift-4 Doble extension
- cela fonctionne très bien dans tous les cas.
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 méthode suivante traite les nombres positifs et négatifs contrairement à la plupart des solutions ici.
Il fonctionne même pour la monnaie.
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];
sortie est comme ci-dessous
In Currency mode
'999' ---- '9.0'
'999.9' ---- '.0k'
'999999.9' ---- '.0m'
'-1000.1' ---- '-.0k'
'-0.9' ---- '-"151910920".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'
j'ai créé la méthode ci-dessus basée sur L'inspiration originale de Kyle @Begeman du lien partagé par @Pandiyan Cool. Merci à @Jeff B pour le code initial en Javascript du lien suivant. est là une façon de arrondir les chiffres dans un format facile à lire? (par exemple $ 1.1 k)
Swift 2.2 en double extension:
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])"
}
}
}
version Swift 4.0 de la réponse 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])
}
pourquoi c'est si difficile pour vous?
cela peut être aussi simple que ceci:
-(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;
}